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

嵌入式:Linux软件编程:线程

一、线程:进程内的轻量级执行单元

1. 基本概念

进程是资源分配的基本单位,而线程是CPU 调度的基本单位。一个进程可以包含多个线程,线程共享进程的内存空间(文本段、数据段、堆区等),但拥有独立的栈区和寄存器。

  • 线程是一个轻量级的进程
    • 线程本质就是一个进程
    • 线程和进程不完全一致,轻量指空间,进程空间和线程空间管理方法不同

2. 线程与进程的核心区别

维度进程线程
资源分配独立地址空间,资源独占共享进程资源
切换开销大(需切换地址空间)小(仅切换栈和寄存器)
通信方式需 IPC(如管道、信号量)直接访问共享内存
独立性高(一个崩溃不影响其他)低(共享资源,相互影响)
进程和线程区别
  1. 线程本质是进程,线程是任务创建、调度、回收的过程
  2. 进程空间:文本段 + 数据段 + 系统数据段
  3. 线程空间:
    • 线程必须位于进程空间内部,没有进程,线程无法独立存在
    • 一个进程中的所有线程共享 文本段 + 数据段 + 堆区,独享 栈区
    • 线程独享的栈区默认认为 8M
    • 一个进程中的多个线程切换调度任务时,资源开销比较小
  4. 进程和线程核心区别:

    • 线程是 CPU 任务调度的最小单元
    • 进程是 操作系统资源分配的最小单元

    3. 多进程和多线程的优缺点

    场景多进程多线程对比
    效率切换需重新映射物理地址,资源开销大同一进程内切换,资源开销小多线程 > 多进程
    通信无共享空间,需进程间通信(IPC)有共享空间,定义共享变量即可交换数据多线程 > 多进程
    资源竞争无共享空间,不存在资源竞争共享空间通信,需保证互斥性(防资源竞争)多进程 > 多线程
    安全空间独立,一个进程崩溃不影响其他进程共用进程空间,一线程崩溃可能导致进程退出(其余线程失效)多进程 > 多线程


4. 线程的调度

  • 与进程调度规则一致
  • 宏观并行(多线程同时执行的表象),微观串行(CPU 实际分时切换执行)

5. 线程的消亡

  • 线程结束后需回收线程空间,否则产生 僵尸线程(资源泄漏)

6. 线程的创建与终止

  • 创建线程:通过pthread_create()函数,需指定线程执行的函数、参数等。
  • 终止线程pthread_exit()主动结束线程,pthread_cancel()可取消其他线程。
  • 等待线程pthread_join()阻塞等待线程结束并回收资源,类似进程的wait()

7. 线程的函数接口

(1)进程接口 vs 线程接口对比
进程接口线程接口功能
forkpthread_create创建进程 / 线程
exitpthread_exit结束进程 / 线程
waitpthread_join回收进程 / 线程资源
(2)pthread_create
int pthread_create(pthread_t *thread,         // 存放线程ID的地址const pthread_attr_t *attr,// 线程属性(默认传NULL)void *(*start_routine)(void *), // 线程函数入口void *arg                  // 传给线程的参数
);

  • 功能:在进程内创建新线程
  • 返回值:成功返回0,失败返回错误码
(3)pthread_self
pthread_t pthread_self(void);

  • 功能:获取当前线程的 ID
(4)pthread_exit
void pthread_exit(void *retval);

  • 功能:主动结束当前线程
  • 参数retval为线程退出时的返回值(可被pthread_join捕获)
(5)pthread_join
int pthread_join(pthread_t thread,  // 要回收的线程IDvoid **retval      // 存放线程退出值的地址(可选,传NULL则忽略)
);

  • 功能
    • 阻塞等待目标线程结束,回收其资源;
    • 同步功能(等待线程执行完毕)。
  • 返回值:成功返回0,失败返回错误码。
注意:
  • 若目标线程未退出,pthread_join会一直阻塞;
  • 通过retval可获取线程通过pthread_exit设置的退出值。
  • pthread_join具备同步功能
#include "../head.h"// 线程函数:符合pthread库要求的函数签名(返回值void*,参数void*)
void *thread1(void *arg)
{   //可以合并为一个,只不过运行的代码一样而已printf("线程(TID:%#lx)开始运行\n",pthread_self());return NULL;
}
// void *thread2(void *arg)
// {
//     printf("线程(TID:%#lx)开始运行\n",pthread_self());//     return NULL;
// }
// void *thread3(void *arg)
// {
//     printf("线程(TID:%#lx)开始运行\n",pthread_self());//     return NULL;
// }int main (void)
{int ret1 = 0;int ret2 = 0;int ret3 = 0;pthread_t tid1;pthread_t tid2;pthread_t tid3;//thread:存放线程ID空间的 首地址// attr:线程的属性,默认属性NULL// start_routine:线程函数的入口// arg:线程传入的参数ret1 = pthread_create(&tid1,NULL,thread1,NULL);if(ret1 != 0){perror("fail to pthread_create\n");return -1;}ret2 = pthread_create(&tid2,NULL,thread1,NULL);if(ret2 != 0){perror("fail to pthread_create\n");return -1;}ret3 = pthread_create(&tid3,NULL,thread1,NULL);if(ret3 != 0){perror("fail to pthread_create\n");return -1;}// printf("线程(TID:%#lx)创建成功\n",tid);while(1){//线程执行的同时进程也在执行//防止进程先结束}return 0;
}
#include "../head.h"void *thread1(void *arg)
{printf("线程1(ITD:%#lx)开始执行\n", pthread_self());pthread_exit("线程1退出");return NULL;
}void *thread2(void *arg)
{printf("线程2(ITD:%#lx)开始执行\n", pthread_self());pthread_exit("线程2退出");return NULL;
}void *thread3(void *arg)
{printf("线程3(ITD:%#lx)开始执行\n", pthread_self());pthread_exit("线程3退出");return NULL;
}int main(void)
{pthread_t tid[3];int i = 0;// 函数指针数组// 是一个数组 数组里是指向函数的指针void *(*p[3])(void *) = {thread1, thread2, thread3};void *pret = NULL;//循环创建for (i = 0; i < 3; i++){pthread_create(&tid[i], NULL, p[i], NULL);}//循环退出for(i = 0;i < 3; i++){   // 具有阻塞的功能   回收线程pthread_join(tid[i],&pret);printf("线程退出状态:%s\n",(char *)pret);//pret本来是void * }#if 0pthread_t tid1;pthread_t tid2;pthread_t tid3;pthread_create(&tid1, NULL, thread1, NULL);pthread_create(&tid2, NULL, thread2, NULL);pthread_create(&tid3, NULL, thread3, NULL);
#endifwhile (1){}return 0;
}

8. 线程同步机制

由于线程共享资源,需通过同步机制避免数据竞争:

  • 互斥锁(pthread_mutex_t:确保同一时间只有一个线程访问临界资源(如全局变量)。
  • 条件变量(pthread_cond_t:让线程等待特定条件满足后再执行(如 "队列非空" 时消费数据)。
  • 信号量:控制同时访问资源的线程数量(如限制 5 个线程同时读写文件)。

三、总结

进程是操作系统资源分配的基本单位,拥有独立的内存空间和完整的生命周期;线程是轻量级的执行单元,共享进程资源,适合高并发场景。理解进程的内存布局、调度机制和状态流转,掌握线程的同步方法,是编写高效 Linux 多任务程序的基础。

http://www.xdnf.cn/news/1305613.html

相关文章:

  • 【详细操作指南】如何将 Moodle 与编辑器连接,以修改文档、检查和批改作业等
  • 2025年最新油管视频下载,附MassTube下载软件地址
  • 【Canvas与玻璃光】铝圈蓝底玻璃光按钮
  • 华为实验综合小练习
  • YAML:锚点深度解析,告别重复,拥抱优雅的配置艺术
  • 第二十四天:虚函数与纯虚函数
  • 【科研绘图系列】R语言绘制三维曲线图
  • MySQL多表查询案例
  • 关系型数据库从入门到精通:MySQL 核心知识全解析
  • 单片机常用通信协议(一)
  • ubuntu 24.04 通过部署ollama提供大模型api接口
  • Storage.AI解读:构建AI数据基础设施的开放标准
  • 【万字精讲】 左枝清减·右枝丰盈:C++构筑的二叉搜索森林
  • Java 中使用阿里云日志服务(SLS)完整指南
  • nifi 增量处理组件
  • 区块链:用数学重构信任的数字文明基石
  • 【0基础3ds Max】学习计划
  • 007TG洞察:特斯拉Robotaxi成本降低84%?技术驱动的效率革命对营销自动化的启示
  • 以下是对智能电梯控制系统功能及系统云端平台设计要点的详细分析,结合用户提供的梯控系统网络架构设计和系统软硬件组成,分点论述并补充关键要点:
  • 深度解读 Browser-Use:让 AI 驱动浏览器自动化成为可能
  • 初识CNN02——认识CNN2
  • 数据结构初阶:排序算法(二)交换排序
  • Boost库中boost::function函数使用详解
  • Redis面试精讲 Day 22:Redis布隆过滤器应用场景
  • 测控一体化闸门驱动灌区信息化升级的核心引擎
  • 波浪模型SWAN学习(1)——模型编译与波浪折射模拟(Test of the refraction formulation)
  • yolo安装
  • es7.x中分片和节点关系以及查看节点数
  • WEB安全--Java安全--Servlet内存马
  • 前端基础知识版本控制系列 - 01( 对版本管理的理解)