news 2026/8/14 16:11:07

学习笔记 | Linux多线程基础:从线程创建到资源回收

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
学习笔记 | Linux多线程基础:从线程创建到资源回收

一,为什么需要多线程

1.1 什么是线程

进程是资源分配的最小单位,线程是CPU调度的最小单位。
一个进程内部可以创建多个线程,所有线程共享该进程的地址空间全局变量文件描述符;每个线程都由自己独立栈,寄存器。

1.2 需要多线程的原因

①可以充分利用多核的CPU算力,多个线程分配到不同的CPU核并行执行,提升整体的运算吞吐量。
🔺单核CPU下多线程是并发不是并行,靠时间片轮转切换。
②避免程序阻塞,提升响应能力,例如:网络服务器中,一个线程等待客户端的数据,其他线程继续处理其他连接。
③线程切换开销远小于进程,线程之间的切换,只需要切换寄存器,栈,切换成本低。
④方便共享数据,线程可以直接读取全局变量。

场景类型特点多线程作用典型例子
CPU密集型程序主要消耗CPU计算资源将计算任务分解到多个CPU核心,并行执行,缩短总耗时视频编码,科学计算,图像渲染
IO密集型程序主要等待输入和输出操作一个线程等待IO时,其他线程继续工作,避免CPU空闲Web服务器,数据库,下载工具

二,线程和进程的关系及区别

2.1 二者的区别

对比项进程线程
基本空间资源分配的基本单位CPU调度的基本单位
地址空间独立拥有共享进程的地址空间
创建开销
切换开销
隔离性

2.2 线程独有的资源(私有)

线程ID,一组寄存器(用于上下文切换),栈(存放局部变量,函数调用),error(错误码),信号屏蔽字,调度优先级

2.3线程共享的资源(共有)

内存资源和系统资源。

三,线程控制

3.1 POSIX线程库

需要引入头文件<pthread.h>

3.2 函数

pthread_create:创建线程的入口函数,所有多线程程序都是从这里开始。返回的是pthread_t类型的线程ID
pthread_join / pthread_detach:资源回收的两种方式,join是手动回收,detach是自动回收。
pthread_exit / pthread_cancel:线程结束的两种方式,exit是终止自己,cancel是终止同一进程中的其他线程。

3.3 线程等待

为什么需要线程等待?
①已经退出的线程,其空间没有被释放,仍然在进程的空间地址内。
②创建新的线程不会复用刚才退出线程的地址空间。
pthread_join函数
作用:等待子进程结束,并回收它的资源。

3.4 分离线程

3.4.1 为什么需要分离线程

默认形况下,新创建的线程是 joinable 的;线程退出后,必须用pthread_join回收资源,否则会造成资源浪费;如果不关心线程返回值,每次都要join是一种负担。

3.4.2 分离线程的作用

告诉系统:线程退出时自动释放资源,无需再等待pthread_join

四,共享资源和竞态条件

4.1 多个线程修改同一个变量会发生什么

多个线程同时修改同一个全局变量,没有任何保护,会产生竞态条件。这个时候就可以通过添加锁来保证同一时刻只有一个线程进入临界区操作资源。
竞态条件:程序的最终结果,依赖于多个线程的CPU调度执行时序。
示例:多个线程同时计数累加,实际运行结果小于预期值,因为一个线程读取变量之后,还没写回,就被内核切走,另一个线程修改了同一个变量,数据被覆盖丢失。

五,常见问题汇总

1.并发和并行有什么区别?
并发强调多个任务在一段时间内交替进行,不一定是同时进行;
并行强调的是多个任务在同一时刻同时执行,通常需要多个CPU核心。

2.创建线程之后,线程的执行顺序是固定的吗?
不是固定的,线程创建成功之后执行的顺序通常由操作系统调度器决定顺序。

3.为什么不能用sleep代替pthread_join?
sleep只能让当前线程暂停一段时间,不能保证目标线程已经执行完成。
例如:线程任务可能因为系统负载,CPU调度或任务复杂度不同,执行时间超过预期的睡眠时间,这样的情况下,sleep睡眠时间一过,主线程继续向下执行了,就不会等待指定线程执行完成,只有pthread_join是真正的等待指定线程结束的操作。

4.pthread_join 和 pthread_detach 有什么区别?

对比项pthread_joinpthread_detach
是否等待线程结束是,调用后线程阻塞等待目标线程退出否,立即返回,不阻塞
是否能获取返回值可以不可以,线程退出后直接丢弃
资源释放时机调用之后才回收线程资源,如果不join ,线程结束后资源不会释放,变成僵尸进程线程一旦执行结束,系统自动回收线程资源,无须外部调用回收函数
适用场景需要拿到子线程执行结果,主线程要等待子线程做完任务往下执行不关心线程返回结果,不需要等待线程结束,做完任务线程自动销毁

5.为什么需要pthread_join呢?
没有调用这个函数的话,如果主线程直接返回,或者进程中任意一个线程调用exit,整个进程都会结束,进程中的其他线程也会被终止,因此调用 pthread_join 后,主线程会等待子线程完成之后才会继续执行。

6.循环创建线程时,为什么不能直接传递&i?
如果传 &i,当线程真正开始运行时,i 的值可能已经被修改,导致多个线程读取到相同的或者错误的值。
解决办法:为每个线程准备独立的参数,可以增加一个数组,如下:

int args[3]; for (int i = 0; i < 3; ++i) { args[i] = i; pthread_create(&threads[i], NULL, worker, &args[i]); }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/14 15:58:50

7.vue指令3

内容v-if, v-else,v-else-if步骤添加数据添加标签添加指令<p v-if"number1">性别男</p> <p v-else>性别女</p>注意else需要紧挨if使用不能单独存在显示内容在<p></p>中间v-else-if用于复杂场景注意两个数据之间要用,(英&#xf…

作者头像 李华
网站建设 2026/8/14 15:57:16

3分钟装完全部VC++运行库:VisualCppRedist AIO 快速上手指南

3分钟装完全部VC运行库&#xff1a;VisualCppRedist AIO 快速上手指南 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 上周五晚上&#xff0c;我打开一个下载了两…

作者头像 李华
网站建设 2026/8/14 15:55:03

社区健身小程序开发实战:从需求分析到上线全流程指南

社区健身小程序开发实战&#xff1a;从需求分析到上线全流程指南 在全民健身与数字化社区深度融合的背景下&#xff0c;“社区健身”小程序已成为连接居民、物业与健身资源的核心载体。针对“社区健身”这一关键词&#xff0c;本文将从技术选型、数据建模、核心功能实现到部署上…

作者头像 李华
网站建设 2026/8/14 15:53:50

2026微信小程序开发费用需要多少?哪个更具性价比?

2026年微信小程序开发费用需要多少&#xff1f;哪个更具性价比&#xff1f;其实这个问题&#xff0c;2026年问的人特别多。先看一组数据&#xff1a;艾瑞咨询《2026年中国小程序生态发展报告》显示&#xff0c;小程序活跃用户规模已突破10亿&#xff0c;市场交易规模达1.2万亿元…

作者头像 李华