当前位置: 首页 > news >正文

linux应用软件编程:线程

一、线程的概念

1.定义

线程是由某个进程的创建。<线程是操作系统任务分配的最小单位。>

2.线程的创建

进程创建线程时,会为其分配独立的“栈区空间(默认8M)”。线程和所在进程,以及进程中的其他线程,共用进程的堆区、数据区、文本去。

3.线程的调度

宏观并行,微观串行。

4.线程的消亡

线程的退出

回收线程的资源空间

5.进程和线程的区别

进程线程
定义进程是操作系统资源分配的最小单位线程是操作系统任务调度的最小单位
资源消耗资源消耗大,每次创建资源开销小,只需要所在进程为其开辟8M的栈区空间
效率角度由操作系统所创建,创建时耗时比线程大,跨进程调度比跨线程调度慢由所在进程创建
通信角度进程间不能直接通信,需要使用进程间通信机制(IPC机制)通信简单,可以使用线程共享的区域进行通信(比如全局变量)
安全性角度进程安全性比线程高,各进程空间独立线程没有进程安全性好,一个线程异常可能影响同一进程中的所有线程。

二、实现线程间编程

(一)线程编程的步骤

1.线程的创建

  •  int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
    void *(*start_routine) (void *), void *arg);

功能:创建一个新的线程

参数:
thread : 保存线程ID的变量地址
attr:线程属性的对象地址
NULL : 按照默认属性创建
start_routine:函数的指针:指向线程启动后要执行的任务(线程任务函数)
arg:为线程任务函数传递的参数
返回值:
成功:0
失败:非0

2.线程的调度

由操作系统调度

3.线程消亡: 
1. 线程退出:
1)在线程任务函数中使用return结束线程
2)pthread_exit(NULL)退出线程;
2. 线程回收:pthread_join(tid, NULL);

  • void pthread_exit(void *retval);

功能:退出一个线程任务
参数:
retval:向回收的线程传递的参数的地址
NULL: 表示不传递参数

  • int pthread_join(pthread_t thread, void **retval);

功能:阻塞等待回收线程资源空间
参数:
thread:要回收的线程ID
retval:用来保存线程退出时传递的参数
NULL: 不接收传递的参数
返回值:
成功:0
失败:-1

(二)线程回收的策略

1. 分离属性的线程:不需要回收,由操作系统回收。(没有空闲的线程可帮忙回收时)
2. 非分离属性的线程:pthread_join()阻塞回收

  • 线程属性:

1. 分离属性:不需要被其他线程回收的线程称为分离属性得到线程,将来会被操作系统所回收
int pthread_detach(pthread_t thread);
功能:将线程设置成分离属性的线程
2. 非分离属性:可以被其他线程回收或者结束的线程,称为非分离属性的线程
(默认属性:非分离属性)

三、线程间通信——使用全局变量通信

  • 临界资源:多个线程可以同时访问的资源称为临界资源:比如,全局变量、共享内存区域等

多个线程在访问临界资源时,存在资源竞争问题。

1.解决资源竞争问题——采用互斥机制

  • 互斥机制:多个线程访问临界资源时,具有排他性访问的机制(一次只允许一个线程对该临界资源进行访问)。

2.实现步骤

1. 创建互斥锁:pthread_mutex_t
2. 初始化互斥锁:pthread_mutex_init();

  • int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);

功能:初始化互斥锁
参数:
mutex:锁对象地址
attr:锁的属性 (NULL:默认属性)
返回值:
成功:0
失败:-1
3. 加锁:int pthread_mutex_lock(pthread_mutex_t *mutex);
4. 解锁:int pthread_mutex_unlock(pthread_mutex_t *mutex);
5. 销毁锁:int pthread_mutex_destroy(pthread_mutex_t *mutex);

3.实现过程及示例

四、线程间的同步通信

(一)概念

1.定义:

线程间同步机制:让多个线程在执行某个任务时,具有先后顺序的执行。

2.实现途径

通过信号量,实现线程间同步。

(二)操作步骤

1. 定义信号量对象 :sem_t 
2. 初始化信号量 : sem_init();

  • int sem_init(sem_t *sem, int pshared, unsigned int value);

功能:初始化信号量
参数:
sem:要初始化的信号量对象地址
pshared:
0 : 线程间共享
非0 : 进程间共享
value:信号量的初始值(初始资源数)
返回值:
成功:0
失败:-1
3.申请信号量: P操作 :int sem_wait(sem_t *sem);
释放信号量:V操作:int sem_post(sem_t *sem);
PV操作
4. 销毁信号量:int sem_destroy(sem_t *sem);

(三)实现过程

(四)具体示例程序

创建三个线程,分别让这三个线程按照顺序打印:A-->B-->C-->A-->B-->C

五、锁进程(互斥锁、信号量、读写锁、自旋锁)

1.死锁定义

死锁指的是在多线程环境中,每个执行流(线程)都有未释放的资源,且互相请求对方未释放资源,从而导致陷入永久等待状态的情况。

2.产生的原因

  • 忘记释放锁
  •  重复加锁
  • 多线程多锁,抢占锁资源不当

3.产生死锁的四个必要条件

一个资源每次只能被一个进程使用(一个执行流获取锁后,其它执行流不能再获取该锁)。

一个进程因请求资源而阻塞时,对已获得的资源保持不放(执行流本身使用着一把锁并不释放,还在请求别的锁)。

进程已获得的资源,在末使用完之前,不能强行剥夺(A执行流拿着锁,其它执行流不能释放)。

  • 互斥条件
  • 请求与保持条件
  • 不剥夺条件
  • 循环等待条件

若干进程之间形成一种头尾相接的循环等待资源关系(多个执行流拿着对方想要的锁,并且各执行流还去请求对方的锁)。

4.解决方法

  • 锁一定要成对出现
  • 使线程的加锁顺序一致
  • 破坏环路等待条件

          使用非阻塞锁,一旦线程发现请求的锁被使用,就去释放自己拥有的锁

              pthread_mutex_trylock();
int sem_trywait(sem_t *sem);

六、进程间通信——IPC机制

1.采用IPC机制通信的原因

        进程空间独立,无法直接通信,需要IPC机制实现。

2.同一主机进程间的通信

无名管道、有名管道、信号(进程间通信)

共享内存(效率最高)、消息队列、信号量集(信号灯)

  • 古老的通信方式
  • IPC对象通信
  • 主要应用在不同主机的通信方式

socket通信:网络通信

http://www.dtcms.com/a/337008.html

相关文章:

  • 使用Idea安装JDK
  • 04.IO 重定向和管道
  • 【深度学习】pytorch深度学习框架的环境配置
  • 如何在服务器 clone github 项目
  • axure chrome 浏览器插件的使用
  • goland怎么取消自动删除未使用的包
  • 学习链接。
  • 【秋招笔试】2025.08.17字节跳动秋招机考真题
  • 论文阅读 2025-8-9 [DiC, DropKey]
  • C++中内存池(Memory Pool)详解和完整示例
  • python实现pdfs合并
  • Leetcode 深度优先搜索 (3)
  • WPF中BindingList<T>和List<T>
  • vue3 + antd实现简单的图片点开可以缩小放大查看
  • 浅谈 Python 正则表达式中的 groups()
  • Linux文件相关命令
  • Disbursement on Quarantine Policy(概率、逆元计算期望)
  • 寻北仪如何靠“小”征服地下世界?
  • AI需要防火墙,云计算需要重新构想
  • 20. 云计算-多租户
  • 猫头虎AI分享|一款智能量化交易系统:QuantCell,从数据收集到策略执行全流程自动化
  • C++ 多进程编程深度解析【C++进阶每日一学】
  • 人工智能技术爆发的时代,AI工具和大模型对行业的深刻变革及实际应用!
  • 面向R语言用户的Highcharts
  • DR200差速移动机器人的多功能感知系统与多场景应用
  • 【网络安全实验报告】实验二: 后门木马配置及分析
  • 【网络安全实验报告】实验三:古典加密算法的实现
  • 数字化转型:概念性名词浅谈(第四十一讲)
  • 如何在VS Code中使用Copilot与MCP服务器增强开发体验
  • ThinkPHP的安装运行和调试