多线程入门

1 创建线程

下面的程序,我们可以用它来创建一个 POSIX 线程:

#include <pthread.h>
pthread_create (myThread, attr, start_routine, arg) 

在这里,pthread_create 创建一个新的线程,并让它可执行。下面是关于参数的说明: 

参数描述
myThread指向线程标识符指针
attr一个不透明的属性对象,可以被用来设置线程属性。您可以指定线程属性对象,也可以使用默认值 NULL。一般不需要关注,直接用NULL即可。
start_routine线程运行函数起始地址,一旦线程被创建就会执行。函数内部就是子线程要运行的内容。
arg运行函数的参数。必须通过把引用作为指针强制转换为 void 类型进行传递。如果没有传递参数,则使用 NULL。一般不需要关注,直接用NULL即可。

2 终止线程

终止线程可采用return NUL自动退出,也可以采用pthread_exit(NULL)强制退出。

3 示例

3.1 示例代码

该代码先执行main函数,然后创建了一个子线程thread_func,此时就存在两个线程,一个主线程,一个子线程。主线程运行一个计算(for循环i);子线程运行一个计算(for循环j)。最后主线程计算结束,子线程计算结束,子线程退出,主线程退出。整个程序结束。

#include <pthread.h>
#include <unistd.h>
#include <stdio.h>void *thread_func(void *arg)
{while (1){for (int j = 0; j < 8; j++){printf("sub:%d\n", j);usleep(10);}if(true/*线程不在使用了,可以退出*/){break;}else{//子线程后面还要使用usleep(10*1000);continue;//进入下个循环}}printf("sub thread return\n");return NULL;
}int main()
{pthread_t tid;pthread_create(&tid, NULL, thread_func, NULL);for (int i = 0; i < 8; i++){printf("main:%d\n", i);usleep(10);}pthread_join(tid, NULL);printf("main thread: all threads exit.\n");return 0;
}

3.2 编译

编译脚本为gcc Demo1.cpp -o Demo1 -lpthread。会生成名字为Demo的可执行程序。

Demo1.cpp中有使用线程技术,需要链接pthread库,即在编译脚本中添加-lpthread。

3.3 运行

./Demo1就是运行。运行逻辑示意图如下。

(1)主线程逻辑图:

(2)子线程逻辑图:

 (3)CPU内核使用情况

总结: 如果只有一个主线程,则只能使用一个主线程内核,所以对于耗时较大的任务,使用多线程可以提高性能。 

3.4 结果分析

可以看到结果,主线程main计算和子线程sub计算同时运行,节省了时间。

下面我们打印时间,进行对比。

(1)代码示例:

 (2)编译运行结果

由此可见,使用一个子线程和一个主线程来进行2个计算,耗时较短,这是因为两个子线程分别持有一个CPU内核,并行进行计算。 缩短了总共时间

另外创建线程也会耗时,如果计算耗时小于创建线程的耗时,则2个线程总共耗时不会优于一个线程,即总共耗时:创建线程耗时+计算1耗时+计算2耗时....。

3.5 源代码

3.3中统计时间的源代码。

Demo1.cpp

#include <pthread.h>
#include <unistd.h>
#include <stdio.h>#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
struct timeval time1, time2;void *thread_func(void *arg)
{// 执行一些操作...int totalSub = 0;for (int j = 0; j < 80; j++){int jk = ((j << 2) * 8) >> 2;int jl = ((j << 4) * 8) >> 4;totalSub = totalSub + jk + jl; // 计算1usleep(10 * 1000);}printf("sub total:%d\n", totalSub);printf("sub thread return\n");return NULL;
}int main()
{double elapsed_time = 0.0;gettimeofday(&time1, NULL);pthread_t tid;pthread_create(&tid, NULL, thread_func, NULL);int totalmain = 0;for (int i = 0; i < 10; i++){int ik = ((i << 2) * 8) >> 2;int il = ((i << 4) * 8) >> 4;totalmain = totalmain + il; // 计算2usleep(10 * 1000);}printf("main total:%d\n", totalmain);pthread_join(tid, NULL);gettimeofday(&time2, NULL);elapsed_time = (time2.tv_sec - time1.tv_sec) * 1000 + (time2.tv_usec - time1.tv_usec) / 1000;printf("Elapsed time: %lf(ms)\n", elapsed_time);printf("main thread: all threads exit.\n");return 0;
}

 Demo2.cpp 

#include <pthread.h>
#include <unistd.h>
#include <stdio.h>#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
struct timeval time1, time2;
int main()
{double elapsed_time = 0.0;gettimeofday(&time1, NULL);int totalSub = 0;int totalmain = 0;for (int j = 0; j < 80; j++){int jk = ((j << 2) * 8) >> 2;int jl = ((j << 4) * 8) >> 4;totalSub = totalSub + jk + jl; // 计算1usleep(10*1000);}printf("main total:%d\n", totalSub);for (int i = 0; i < 10; i++){int ik = ((i << 2) * 8) >> 2;int il = ((i << 4) * 8) >> 4;totalmain = totalmain + il; // 计算2usleep(10*1000);}printf("sub total:%d\n", totalSub);gettimeofday(&time2, NULL);elapsed_time = (time2.tv_sec - time1.tv_sec) * 1000 + (time2.tv_usec - time1.tv_usec)/1000;printf("Elapsed time: %lf(ms)\n", elapsed_time);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/155798.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QT自制软键盘 最完美、最简单、跟自带虚拟键盘一样

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 QT自制软键盘 最完美、最简单、跟自带虚拟键盘一样 Chapter1 QT自制软键盘 最完美、最简单、跟自带虚拟键盘一样一、本自制虚拟键盘特点二、windows打开系统自带软键盘三、让…

3、在docker 容器中安装tomcat

&#xff11;、在服务器上查找tomcat镜像,查看前5条 docker search tomcat --limit 5​​​​​​​ 2、拉取镜像到本地 拉取官方的tomcat到本地 docker pull tomcat:9.0.34-jdk8 3、查看本地镜像 docker images |grep tomcat 4、启动tomcat 服务 使用默认配置 docker ru…

如何选择一个向量数据库:Elastic Cloud 和 Zilliz Cloud 面面观

随着以 Milvus 为代表的向量数据库在 AI 产业界越来越受欢迎&#xff0c;诸如 Elasticsearch 之类的传统数据库和检索系统也开始行动起来&#xff0c;纷纷在快速集成专门的向量检索插件方面展开角逐。 例如&#xff0c;在提供类似插件的传统数据库中&#xff0c;Elasticsearch …

VAE模型(详细推导+实例代码)

文章目录 EM算法思路E步M步直观感觉 GMM模型VAEVAE思想从GMM到VAE公式推导重参数VAE神经网络另一个视角的VAE思想为什么引入encoder为什么要重参数噪声与重建 Discrete VAE 本文会从EM算法&#xff0c;GMM模型一步一步的的推导&#xff0c;在过渡到VAE模型&#xff0c;如果有熟…

棱镜七彩参编!开源领域4项团体标准正式发布

近日&#xff0c;中电标2023年第27号团体标准公告正式发布&#xff0c;《T/CESA 1270.2-2023 信息技术 开源治理 第 2 部分&#xff1a;企业治理评估模型》、《T/CESA 1270.3-2023 信息技术 开源治理 第 3 部分&#xff1a;社区治理框架》、《T/CESA 1270.5-2023 信息技术 开源…

信创办公–基于WPS的EXCEL最佳实践系列 (单元格与行列)

信创办公–基于WPS的EXCEL最佳实践系列 &#xff08;单元格与行列&#xff09; 目录 应用背景操作步骤1、插入和删除行和列2、合并单元格3、调整行高与列宽4、隐藏行与列5、修改单元格对齐和缩进6、更改字体7、使用格式刷8、设置单元格内的文本自动换行9、应用单元格样式10、插…

STM32F4X I2C LM75

STM32F4X I2C LM75 I2C协议讲解I2C接线I2C协议波形I2C起始信号I2C停止信号I2C应答信号I2C寻址I2C地址格式 I2C数据传输 LM75ALM75A介绍LM75A引脚说明LM75A地址LM75A寄存器LM75A I2C协议写配置寄存器读配置寄存器写Tos和Thyst寄存器读Tos Thyst Temp寄存器LM75A温度计算 LM75A例…

力扣(LeetCode)2578. 最小和分割(C++)

哈希集合 请读者思考&#xff0c;num拆分成num1和num2&#xff0c;要使得num1 num2最小&#xff0c;应满足两条性质&#xff1a; num1和num2位数相同&#xff0c;或最多差一位。num1和num2应按数值从小到大在num中取数。 想到统计num的位数&#xff0c;以实现性质1的需要&a…

淘宝天猫商品历史价格API接口

获取淘宝商品历史价格接口的步骤如下&#xff1a; 注册淘宝开放平台&#xff1a;首先在淘宝开放平台上注册一个账号&#xff0c;并进行登录。创建应用&#xff1a;在淘宝开放平台上创建一个应用&#xff0c;并获取该应用的App Key和App Secret&#xff0c;用于后续的接口调用。…

【数据结构】二叉树的链式结构及实现

目录 1. 前置说明 2. 二叉树的遍历 2.1 前序、中序以及后序遍历 2.2 层序遍历 3. 节点个数及高度等 4. 二叉树的创建和销毁 1. 前置说明 在学习二叉树的基本操作前&#xff0c;需先要创建一棵二叉树&#xff0c;然后才能学习其相关的基本操作。由于现在大家对二叉树结构…

区块链技术的飞跃: 2023年的数字革命

随着时代的推进和技术的不断创新&#xff0c;2023年成为区块链技术飞跃发展的一年。区块链&#xff0c;一个曾经只是数字货币领域的技术&#xff0c;现在已经逐渐渗透到各个行业&#xff0c;成为推动数字经济发展的重要力量。在这个数字革命的时代&#xff0c;我们探讨区块链技…

什么是存储服务器?

随着互联网的发展&#xff0c;越来越多的信息会在网络上暴露&#xff0c;所以企业就会更加重视数据&#xff0c;因此更加安全可靠的数据存储服务器受到了大多数人的信赖&#xff0c;今天就让小编带大家了解一下什么是存储服务器吧&#xff01; 存储服务器的含义。存储服务器是…

代理IP端口是什么意思呢?

今天&#xff0c;咱们来聊聊一个小众但很有料的话题——代理IP端口&#xff0c;它可是你纵横互联网世界的好搭子哦&#xff01; 首先&#xff0c;我们得先弄明白&#xff0c;代理IP端口是个啥? 代理IP端口就像是通往网络世界的门票&#xff0c;是你和代理服务器之间的桥梁。…

使用注解新开事务 @Transactional

使用注解新开事务 Transactional(propagation Propagation.REQUIRES_NEW)

使用Perl脚本编写爬虫程序的一些技术问题解答

网络爬虫是一种强大的工具&#xff0c;用于从互联网上收集和提取数据。Perl 作为一种功能强大的脚本语言&#xff0c;提供了丰富的工具和库&#xff0c;使得编写的爬虫程序变得简单而灵活。在使用的过程中大家会遇到一些问题&#xff0c;本文将通过问答方式&#xff0c;解答一些…

Jetson Orin NX 开发指南(6): VINS-Fusion-gpu 的编译和运行

一、前言 由于 Jetson 系列的开发板 CPU 性能不是很好&#xff0c;因此在处理图像数据时往往需要 GPU 加速&#xff0c;而 VINS-Fusion 是针对同步定位与建图&#xff08;SLAM&#xff09;问题中十分出色的视觉算法&#xff0c;但是其在图像处理过程中资源消耗较大&#xff0c…

执行make menuconfig问题的解决

执行make menuconfig 出现问题 在终端输入以下命令执行。 make menuconfig在终端输入上面命令执行时&#xff0c;没有成功运行&#xff0c;出现了如下的问题。 出现这个错误提示意味着在运行 make menuconfig 命令时&#xff0c;系统找不到 ncurses 库。ncurses 是一种文本用…

iPhone手机记笔记工具选择用哪个

iPhone手机大家应该都比较熟悉&#xff0c;其使用性能是比较流畅的&#xff0c;在iPhone手机上记录笔记可以帮助大家快速地进行总结工作、记录工作内容等&#xff0c;在iPhone手机上记笔记工具选择用哪个呢&#xff1f; 可以在iPhone手机上使用的笔记工具是比较多的&#xff0…

Vue3中使用tinymce全功能演示,包括开源功能

效果图&#xff1a; 1、下载插件: npm i tinymce npm i tinymce/tinymce-vue 2、在node_modules文件夹中找到tinymce下的skins复制到项目public文件夹中 &#xff08;可以先创建一个tinymce文件夹&#xff09;&#xff1a; 3、在tinymce官网中下载中文包&#xff0c;并放在刚…

FISCO BCOS | 构建第一个区块链应用程序

本章将介绍基于FISCO BCOS区块链的业务应用场景开发的全流程。介绍包括业务场景分析、合约设计实现、合约编译、区块链开发等。最后&#xff0c;我们介绍一个应用模块实现&#xff0c;即通过我们提供的Java SDK实现对区块链上合约的调用访问。 本教程要求用户熟悉Linux操作环境…