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

Linux学习笔记4:进程和线程的区别

1. 引言

又是摸鱼几天~

在 Linux 系统编程中,进程(Process)与线程(Thread)是并发编程的两大基石。

2. 进程与线程的基本概念

2.1 进程

进程是操作系统分配资源的最小单位。每个进程都拥有独立的地址空间、文件描述符表、信号处理函数等资源。在 Linux 中,内核通过task_struct结构体描述每一个进程。进程间相互隔离,一个进程崩溃通常不会直接导致另一个进程崩溃。

2.2 线程

线程是操作系统调度的最小单位。一个进程内部可以包含多个线程,这些线程共享进程的地址空间、文件描述符等大部分资源,但拥有独立的栈、寄存器状态和程序计数器。在 Linux 中,线程以内核轻量级进程(LWP)的形式实现,通过clone()系统调用创建,指定共享哪些资源。

3. 深入对比:进程 vs 线程

对比维度进程线程
资源拥有独立地址空间、独立资源共享进程地址空间及资源
创建/销毁开销大(需复制页表、文件描述符等)小(仅需分配栈、寄存器上下文)
上下文切换代价较高(切换页表、刷新 TLB)代价较低(同进程下切换无需切换地址空间)
通信方式管道、FIFO、共享内存、消息队列、Socket 等可直接读写共享内存,配合锁/信号量
隔离性与健壮性强隔离,一个进程崩溃不影响其他弱隔离,一个线程崩溃可能拖垮整个进程
适合场景IO 密集型、多核并行、需要高可靠性计算密集型、高并发网络服务、数据共享频繁

4. Linux 中的进程与线程实现

在 Linux 内核层,没有专门的“线程”数据结构,所有执行实体都通过task_struct表示。创建进程使用fork(),创建线程通常使用 POSIX 线程库(pthread),底层会调用clone()并设置恰当的共享标志。例如,使用pthread_create()时,clone()的参数会让新任务与父任务共享内存空间、文件系统信息等,从而实现线程的语义。

下面是一个简单的 pthread 示例:

#include<stdio.h>#include<pthread.h>void*thread_func(void*arg){printf("Hello from thread!\n");returnNULL;}intmain(){pthread_ttid;printf("Main process pid: %d\n",getpid());pthread_create(&tid,NULL,thread_func,NULL);pthread_join(tid,NULL);return0;}

getpid()在进程中返回进程 ID,而在线程中(同一进程)返回的仍然是进程 ID;获取线程 ID 需要使用pthread_self()gettid()系统调用。

5. 调度与上下文切换

Linux 的 CFS(完全公平调度器)以调度实体为单位进行调度,线程就是调度实体。当 CPU 从一个线程切换到另一个线程时,涉及保存当前寄存器、栈指针、程序计数器,并恢复下一个线程的状态。

  • 进程间上下文切换:还需要切换地址空间,包括页表、刷新 TLB 缓存,开销明显高于线程切换。
  • 线程上下文切换:由于共享同一地址空间,这部分操作被省略,因此线程切换更快。

6. 多线程编程的注意事项

虽然线程轻量、通信便捷,但编写正确的多线程程序需要注意以下几点:

  1. 数据竞争:共享数据的访问必须同步,使用互斥锁(pthread_mutex_t)、读写锁、自旋锁等。
  2. 死锁:避免嵌套加锁顺序不一致、持有锁时调用可能阻塞的函数等。
  3. 线程安全:系统库函数(如strtokgmtime)可能内部使用静态缓冲区,需改用可重入版本(strtok_rgmtime_r)。
  4. 惊群效应:多个线程同时等待同一事件时的唤醒风暴,可采用条件变量配合队列或使用SO_REUSEPORT缓解。
  5. 资源清理:线程退出时应确保释放持有的锁及堆内存,推荐使用线程局部存储(TLS)或 RAII 风格封装。
http://www.jsqmd.com/news/1090719/

相关文章:

  • 自动化SOP跟进:提升私域复购率工具常见误区规避
  • 工业级数据采集卡的“内部基建”:从主控MCU到全隔离电源与信号链的硬核拆解
  • 卤水点豆腐和胶体聚沉之间的关系
  • Day9 |删除链表倒数第N个节点 相交链表
  • 技术突破:Python实现QQ音乐API数据解析与资源获取方案
  • DSVW:极简Web漏洞靶场实战指南,从SQL注入到XSS攻防演练
  • 解锁BT下载极速体验:trackerslist项目让你的下载速度飙升300%
  • 【操作系统】经典同步问题:读者-写者 / 哲学家进餐
  • 学习周报 Week 6:目标检测
  • 鸿蒙 ArkTS 实战:Recitation Timer 从状态建模到交互闭环完整解析
  • 2026世界杯AI案例适合写进大学生AI作品集吗
  • OpCore-Simplify:三十分钟完成黑苹果配置的智能化解决方案
  • 从零搭建Selenium自动化测试框架:Python+Pytest实战指南
  • 大模型项目进入生产后,真正难管的不是模型:一套 API 接入与向量检索运行手册
  • MyBatis 与 MyBatis-Plus 面试题汇总——从原理到实战
  • 3DMax新手避坑指南:模型导入、选择与显示的实战解析
  • 5个理由选择FreeShip Plus:零成本专业船舶设计完全指南
  • 应急电源深度实测:锂电池 vs 镁金属空气电池,6个核心维度选型对比
  • NifSkope深度解析:游戏文件编辑架构与扩展开发最佳实践
  • shader开发工具
  • ComfyUI BrushNet图像修复工作流终极配置指南:5个常见错误与解决方案
  • 告别“more than one device/emulator”困扰:精准定位与高效调试指南
  • ComfyUI-Impact-Pack终极指南:5个技巧让AI图像细节清晰如镜
  • DP159RGZ评估模块硬件设计与信号完整性调试实战解析
  • 鸿蒙 ArkTS 实战:Paper Reader 从状态建模到交互闭环完整解析
  • 从线芯排列到传输性能:深度解析超五类与六类水晶头的设计哲学与实战选择
  • 微信网页版访问受限?三分钟教你通过浏览器插件绕过限制
  • 异步爬虫 aiohttp 进阶实战——高并发采集的正确姿势
  • 鸿蒙 ArkTS 实战:Lab Record Book 从状态建模到交互闭环完整解析
  • Python 知识体系深度解析与学习指南