Linux系统编程系列之线程

一、什么是线程

        线程(Thread)是计算机中的基本执行单元,是操作系统调度的最小单位。线程是进程内的一个独立执行流程,一个进程可以包含多个线程,这些线程共享进程的资源,但每个线程都有自己的独立栈空间以及程序计数器。

二、线程与进程的优缺点

        1、线程的优点

        (1)、线程创建和销毁的开销比进程小,因为线程共享进程中的地址空间和其他资源。

        (2)、线程可以同时执行多个任务,提高了系统的并发性能。

        (3)、线程之间的通信和同步比进程之间的通信和同步更快捷和简单,因为线程共享同一进程的内存。

        (4)、线程可用于执行GUI等交互性任务而不会卡住整个应用程序。

        2、线程的缺点

        (1)、 多线程访问共享数据时,需要使用同步技术,否则会导致不可预期的结果。

        (2)、 线程的调试和bug定位比较困难,因为多个线程共享进程的执行环境。

        (3)、 如果线程中出现了异常,可能会影响整个进程。

        3、进程的优点

        (1)、 进程相互独立,不会相互影响,因此更加健壮和安全。

        (2)、进程可以在不同的硬件和操作系统上运行,更具有可移植性。

        (3)、 进程使用管道等IPC(进程间通信)机制可以方便的实现进程之间的通信和同步。

        4、进程的缺点

        (1)、进程创建和销毁的开销比较大,因为每个进程都需要独立的地址空间和系统资源。

        (2)、进程之间通信和同步需要使用IPC技术,比较繁琐和复杂。

        (3)、进程的并发性能比较差,不能同时执行多个任务。

三、线程的使用场景

        1、多任务处理:多线程可以同时处理多个任务,提高程序的执行效率和响应速度。

        2、并发访问:当多个线程同时访问共享资源时,需要使用线程控制技术,避免出现竞态条件和死锁等问题。

        3、异步编程:线程可以在后台执行一些耗时的操作,不会阻塞主线程,提高程序的用户体验。

        4、服务器编程:服务器一般要同时处理多个客户端请求,使用多线程可以提高服务器的并发处理能力。

        5、图形界面编程:图形界面程序中需要使用线程避免阻塞用户界面,实现异步更新UI界面。

        6、大数据处理:对于大数据处理和分析,多线程可以提高数据处理的效率和速度。

        7、游戏开发:游戏开发中需要实时更新游戏画面和处理用户输入,需要使用多线程技术实现。

四、与线程有关的函数API

        1、线程的创建

        创建一条POSIX线程非常简单,只需要指定线程的执行函数即可

// 创建一条线程
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);// 接口说明:返回值:成功返回0,失败返回一个错误码参数thread:新线程的TID参数attr:线程属性,若创建标准线程则该参数可设置为NULL参数start_routine:线程函数,是一个回调函数,跟信号的例程函数有点像参数arg:线程函数的参数

         2、线程的退出

        与进程类似,当一条线程执行完毕其任务时,可以使用接口来退出

// 线程的退出
void pthread_exit(void *retval);// 接口说明参数retval:线程的返回值,若线程没有数据可返回则可写成NULLpthread_exit()与exit()的区别
pthread_exit():退出当前线程
exit():退出当前进程(即退出进程中的所有进程)

         3、线程的结合

        与进程类似,线程退出后不会立即释放其所占有的系统资源,而会成为一个僵尸线程。其他线程可使用pthread_join()来释放僵尸线程的资源,并可获得其退出时返回的退出值,该函数接口被称为线程的接合函数:

// 阻塞等待指定线程退出
int pthread_join(pthread_t tid, void **val);// 非阻塞接合指定线程退出
int pthread_tryjoin_np(pthread_t tid, void **retval);// 在指定时间内阻塞接合指定线程的退出
int pthread_timedjoin_np(pthread_t tid, void **retval, const struct timespec *ashtime);// 接口说明(1)若指定tid的线程尚未退出,那么该函数将持续阻塞(2)若只想阻塞等待指定线程tid退出,而不想要其退出值,那么val可置为NULL(3)若指定tid的线程处于分离状态,或者不存在,则该函数会出错返回

        4、获取线程TID

        

// 获取线程TID
pthread_t pthread_self(void);// 接口说明返回值:线程TID该接口类似进程管理中的getpid(),但是进程的PID是系统全局资源,而线程的TID仅限于进程内部的线程间有效。当我们要对某条线程执行发送信号,取消,阻塞接合等操作时,需要用到线程的TID。

        5、线程错误码

        线程函数对系统错误码的处理跟标准C库函数的处理方式有很大不同,标准C库函数会对全局错误码errno进行设置,而线程函数发生错误时会直接返回错误码。以线程接合为例,若要判定接合是否成功,成功的情况下输出僵尸线程的退出值,失败的情况下输出失败的原因,实现代码应该这么写

#include <error.h> // 头文件中定义了errno变量void *val;errno = pthread_join(tid, &val);if(errno == 0)
{printf("成功接合线程,其退出值为:%d\n", (int)val;
}
else
{perror("接合线程失败");
}

        6、函数单例

        许多时候,我们希望某个函数只被严格执行一次,这种需求在一些初始化功能模块中尤为常见,但是如果某个进程中内含多条线程,无法预先知晓哪条线程会先执行,那么初始化就会被执行多次,但如果使用函数单例就会只执行一次。

// 函数单例启动接口
int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));// 接口说明参数once_control:用来关联某个函数单例,被关联的函数单例只会被执行一遍参数init_routine:函数指针指向的函数就是只执行一遍的函数单例// 通常参数once_control指定为函数单例控制pthread_once_t once_control = PTHREAD_ONCE_INIT;

五、案例

// 线程的案例#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <string.h>int flag = 0;   // 简单的标志位来控制同步
char data[100];// 线程1的例程函数,用来接收数据
void *recv_routine(void *arg)
{printf("I am recv_routine, my tid = %ld\n", pthread_self());while(1){if(flag){printf("pthread1 read data: %s\n", data);memset(data, 0, sizeof(data));flag = 0;}}
}// 线程2的例程函数,用来发送数据
void *send_routine(void *arg)
{printf("I am send_routine, my tid = %ld\n", pthread_self());while(1){printf("please input data:\n");fgets(data, 100, stdin);printf("pthread2 send data\n");flag = 1;}
}int main(int argc, char *argv[])
{pthread_t tid1, tid2;// 创建线程1,用来接收数据errno = pthread_create(&tid1, NULL, recv_routine, NULL);if(errno == 0){printf("pthread create recv_routine success, tid = %ld\n", tid1);}else{perror("pthread create recv_routine fail\n");}// 创建线程2,用来发送数据errno = pthread_create(&tid2, NULL, send_routine, NULL);if(errno == 0){printf("pthread create send_routine success, tid = %ld\n", tid2);}else{perror("pthread create send_routine fail\n");}// 一定要加这个,否则主函数直接退出,相当于进程退出,所有线程也退出// 或者加上while(1)等让主函数不退出pthread_exit(0);return 0;
}

六、总结

        线程可以提供系统的并发性,开销比进程更加小,但是不如进程健壮,移植性好。线程有自己的属性,下一篇博客将讲解。

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

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

相关文章

Java后端模拟面试,题集①

1.Spring bean的生命周期 实例化 Instantiation属性赋值 Populate初始化 Initialization销毁 Destruction 2.Spring AOP的创建在bean的哪个时期进行的 &#xff08;图片转载自Spring Bean的完整生命周期&#xff08;带流程图&#xff0c;好记&#xff09;&#xff09; 3.MQ如…

基于SSM的选课排课系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

2023年中国奶牛平均单产量、奶类产量及发展趋势分析:液态奶市场向高端化发展[图]

2022年&#xff0c;我国奶产业素质稳步提升&#xff0c;全国存栏百头以上规模养殖比例达到72%&#xff0c;同比提高2个百分点。奶牛平均单产9.2吨&#xff0c;较2021年增加500千克&#xff1b;规模牧场95%以上配备全混合日粮搅拌车&#xff0c;原料奶生产100%实现机械化挤奶&am…

3D WEB轻量化引擎HOOPS助力3D测量应用蓬勃发展:效率、精度显著提升

在3D开发工具领域&#xff0c;Tech Soft 3D打造的HOOPS SDK已经崭露头角&#xff0c;成为了全球领先的3D领域开发工具提供商。HOOPS SDK包括四种不同的3D软件开发工具&#xff0c;已成为行业的翘楚。 其中&#xff0c;HOOPS Exchange以其CAD数据转换的能力脱颖而出&#xff0c…

如何破解压缩包zip解压密码?

Zip压缩包设置了密码&#xff0c;解压的时候就需要输入正确对密码才能顺利解压出文件&#xff0c;正常当我们解压文件或者删除密码的时候&#xff0c;虽然方法多&#xff0c;但是都需要输入正确的密码才能完成。忘记密码就无法进行操作。 那么&#xff0c;忘记了zip压缩包的密…

leetCode 55.跳跃游戏 贪心算法

给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入…

基于微信小程序的手机在线商城小程序设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言系统主要功能&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…

MySql017——组合查询

一、UNION作用 可用UNION操作符来组合数条SQL查询。 二、UNION 使用规则 1、UNION的使用很简单。所需做的只是给出每条SELECT语句&#xff0c;在各条语句之间放上关键字UNION。2、UNION必须由两条或两条以上的SELECT语句组成&#xff0c;语句之间用关键字UNION分隔&#xff…

专业图像处理软件DxO PhotoLab 7 mac中文特点和功能

DxO PhotoLab 7 mac是一款专业的图像处理软件&#xff0c;它为摄影师和摄影爱好者提供了强大而全面的照片处理和编辑功能。 DxO PhotoLab 7 mac软件特点和功能 强大的RAW和JPEG格式处理能力&#xff1a;DxO PhotoLab 7可以处理来自各种相机的RAW格式图像&#xff0c;包括佳能、…

(SAR)Sentinel-1影像自动下载

基于ASF网站提供的python代码&#xff0c;实现Sentinel-1影像的自动下载&#xff1b; 1、登录ASF网站 登录Sentinel-1影像ASF网站&#xff1a;https://search.asf.alaska.edu/&#xff1b; 点击网站最右侧Sign in图标&#xff0c;进行用户注册&#xff1b; 注册完用户之后&…

【c语言】推箱子

所需知识&#xff1a;c语言枚举&#xff0c;数组&#xff0c;for循环&#xff0c;while循环&#xff0c;switch,case语句&#xff0c;图形库相关函数 1.调整控制台窗口大小 #define _CRT_SECURE_NO_WARNINGS #include <stdlib.h>#include <stdio.h> int main() {…

STM32之DMA

简介 • DMA &#xff08; Direct Memory Access &#xff09;直接存储器存取 &#xff08;可以直接访问STM32内部存储器&#xff0c;如SRAM、程序存储器Flash和寄存器等&#xff09; •DMA可以提供外设和存储器或者存储器和存储器之间的高速数据传输&#xff0c;无须CPU干预&a…

pytorch函数reshape()和view()的区别及张量连续性

目录 1.view() 2.reshape() 3.引用和副本&#xff1a; 4.区别 5.总结 在PyTorch中&#xff0c;tensor可以使用两种方法来改变其形状&#xff1a;view()和reshape()。这两种方法的作用是相当类似的&#xff0c;但是它们在实现上有一些细微的区别。 1.view() view()方法是…

古记事法:Windows 下 16 位汇编环境搭建指南(DOSBox-X 篇)

文章目录 参考环境DOSBox-XWOWWindows On Windows 产生的原因Windows On Windows 的工作原理WOW16 的结束与 WOW64 的未来 在现代操作系统中运行 16 位应用程序DOSBox-X 16 位汇编环境的搭建应用准备挂载自动挂载dosbox-x.conf配置工具 参考 项目描述搜索引擎Bing、GoogleAI 大…

二极管的直流等效电路和微变等效电路

二级管的主要参数 1.IF&#xff08;最大整流的电流&#xff09; 二极管长期工作做能够通过电流的平均最大值&#xff1a;物理意义&#xff1a;功率电流值。 2.UR 二极管最高反向工作电压 需要留有裕度&#xff0c;通常能达到一半的裕度&#xff1b;UR不能等于UBR。 3.IR 未击穿…

自动驾驶技术:现状与未来

自动驾驶技术&#xff1a;现状与未来 文章目录 引言自动驾驶技术的现状自动驾驶技术的挑战自动驾驶技术的未来结论结论 2023星火培训【专项营】Apollo开发者社区布道师倾力打造&#xff0c;包含PnC、新感知等的全新专项课程上线了。理论与实践相结合&#xff0c;全新的PnC培训不…

傅里叶系列 P1 的定价选项

如果您想了解更多信息&#xff0c;请查看第 2 部分和第 3 部分。 一、说明 这是第一篇文章&#xff0c;我将帮助您获得如何使用这个新的强大工具来解决金融中的半分析问题并取代您的蒙特卡洛方法的直觉。 我们都知道并喜欢蒙特卡洛数字积分方法&#xff0c;但是如果我告诉你你可…

机器人中的数值优化(二十)——函数的光滑化技巧

本系列文章主要是我在学习《数值优化》过程中的一些笔记和相关思考&#xff0c;主要的学习资料是深蓝学院的课程《机器人中的数值优化》和高立编著的《数值最优化方法》等&#xff0c;本系列文章篇数较多&#xff0c;不定期更新&#xff0c;上半部分介绍无约束优化&#xff0c;…

嵌入式Linux应用开发-基础知识-第十九章驱动程序基石②

嵌入式Linux应用开发-基础知识-第十九章驱动程序基石② 第十九章 驱动程序基石②19.3 异步通知19.3.1 适用场景19.3.2 使用流程19.3.3 驱动编程19.3.4 应用编程19.3.5 现场编程19.3.6 上机编程19.3.7 异步通知机制内核代码详解 19.4 阻塞与非阻塞19.4.1 应用编程19.4.2 驱动编程…

Unity HDRP Custom Pass 实现场景雪地效果

先使用Shader Graph连一个使用模型法线添加雪地的shader&#xff0c;并赋给一个material。 1.1 先拿到模型世界坐标下的顶点法线&#xff0c;简单处理一下&#xff0c;赋给透明度即可。 给场景添加Custom Pass&#xff0c;剔除不需要的层级。 1.在Hierarchy界面中&#xff…