Linux软件编程(5)线程

前两天学习完了进程有关的内容,今天学习线程这部分的内容,线程和进程很容易搞混,我们还是要搞懂定义,但是学习完了进程,线程这部分内容相对容易理解。

一、什么是线程

线程被叫做轻量级进程,它同样拥有创建、调度、消亡完整流程。

进程和线程的区别:

进程:操作系统资源分配的最小单位

每个进程拥有0‑4G完整虚拟内存空间,分为文本段、数据段、堆等区域,进程之间内存互相独立,互不干扰。

线程:操作系统任务调度的最小单位

线程跑在进程的地址空间里面。同一个进程里的多个线程,共享堆、全局变量、静态变量、字符串常量、代码段;但是每个线程有自己独立的栈空间,局部变量是线程私有的。

简单总结:

进程拥有整套资源;线程只拥有自己栈,其余全部借用父进程的资源。

二、进程与线程核心函数对比

进程 线程

fork() 创建 pthread_create() 创建

exit() 退出 pthread_exit() 退出

wait() 回收子进程 pthread_join() 回收线程

  1. 调度

    线程调度和进程调度规则一致,宏观上看多个线程并发运行,微观上CPU分片交替执行。

  2. 线程消亡

    线程结束之后,如果不调用pthread_join回收资源,就会产生僵尸线程,占用系统资源。

三、线程函数

编译线程程序必须加 -pthread 参数,gcc test.c -o test -pthread。

  1. pthread_create 创建线程

    int pthread_create(pthread_t *thread, const pthread_attr_t *attr,

    void *(*start_routine) (void *), void *arg);

    功能:

    创建线程。

    参数:

    thread:传出参数,存放新线程ID(TID)

    attr:线程属性,一般传NULL,使用默认属性

    start_routine:线程要执行的函数,函数指针

    arg:传给线程函数的参数

    返回值:

    成功返回0,失败返回错误码

    调用完这个函数,新线程立刻开始调度,主线程和子线程谁先跑是不确定的。

  2. pthread_exit 结束线程

    void pthread_exit(void *retval);

    功能:

    用来在线程函数内部结束当前线程。

    参数:

    retval是线程退出的状态值,可以被pthread_join拿到。

    注意:不要在线程里面直接用exit(),exit会把整个进程直接结束,所有线程全部消失。

  3. pthread_join 回收线程

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

    功能:

    等待指定线程结束,回收线程栈资源,具备阻塞特性。

    参数:

    thread:要等待回收的线程ID

    retval:接收线程退出返回值,不需要接收就填NULL

    返回值:

    成功0,失败返回错误码

    阻塞含义:如果子线程还没跑完,主线程卡在join这里原地等待,直到子线程结束才往下走。

    四、分离属性 detach(不用join回收)

普通线程必须pthread_join回收,否则僵尸线程。

设置分离属性之后:线程结束,操作系统自动回收资源,程序就不需要调用pthread_join。

相关接口:

  1. pthread_attr_init:初始化线程属性结构体
  2. pthread_attr_setdetachstate:设置分离状态
  3. pthread_attr_destroy:销毁属性结构体,释放空间

两种写法:创建的时候设置分离属性;或者线程内部调用pthread_detach(self)。

五、多进程 、多线程的优缺点

  1. 运行效率:多线程 > 多进程

线程共享进程地址空间,创建切换开销小;进程要复制完整内存,开销更大。

  1. 安全性:多进程 > 多线程

进程内存完全独立,一个进程崩溃,不会影响别的进程。

同一个进程内,任意一个线程崩溃,整个进程直接挂掉,全部线程一起结束。

  1. 通信实现:多线程 > 多进程

多线程天然共享全局变量、堆内存,直接读写就可以通信。

但是多个线程同时改共享变量,会出现资源竞争,需要加锁保护。

多进程地址空间互相隔离,没有共享内存,必须管道、共享内存这类特殊机制才能通信,实现复杂。

  1. 编程复杂度:多进程 < 多线程

多线程要处理资源竞争、锁、僵尸线程;多进程通信麻烦,但不会出现线程互相干扰的问题。

相关推荐
bosins4 小时前
彻底解决 WSL 2.7+ 空闲自动关闭/内存回收导致 Docker 中断的问题
linux·docker·wsl·dashboard
LongRunning4 小时前
【Linux】H3网络(二)
linux
野生技术架构师4 小时前
2026 Java 面试全套总结,八股 + 场景 + AI 相关面试考点
java·人工智能·面试
香吧香5 小时前
java服务异常日志只打印异常类型,没有堆栈定位分析
java·jvm·异常
qq_2518364575 小时前
AI 疾病自查功能SpringbootAI项目实战 · 技术实现文档
java·ai·ai编程
xx~t5 小时前
嵌入式学习——ARM1
linux·arm开发·嵌入式硬件·arm
xx~t5 小时前
嵌入式——ARM1(详细篇)
linux·arm开发·嵌入式硬件·arm
逆境不可逃6 小时前
Pi Agent 学习笔记:对话太长以后,如何压缩上下文
java
MetaLite6 小时前
JDK 8~26 核心特性一览:从 Stream 到 Scoped Values
java
程序员黎剑6 小时前
JVM-元空间溢出-OutOfMemoryError-Metaspace排查与解决
jvm