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

2026-3-21 多线程编程基础

1 如何理解程序中的并发与并行
编写程序希望实现可并行和高并发。可并行是指多个任务同时执行,这是需要多核硬件作为支撑的;高并发是指程序的组织方式,可以把任务拆解成多个模块独立执行。关键的区别在于,并行是执行层面的同时运行,必须要多核;并发是代码层面的组织方式,单核也可以实现并发。
image
CPU1和CPU2各自有4个颜色的任务块。在同一时刻,两个CPU在同时执行不同任务,这是并行;而在每个CPU内部,不同任务是交替执行的,这是并发。
2 可执行程序、进程、线程
2.1 可执行程序
可执行程序就是磁盘上的一个文件。Windows下就是一个扩展名为.exe的文件,通过双击来运行;Linux下就是一个文件属性包括x的拥有执行权限的文件,通过./文件名称来执行。
2.2 进程
一个可执行程序运行起来了,就叫做创新了一个进程。也就是说,进程就是运行起来的可执行程序。从操作系统角度出发,进程是为了管理程序,一个包括代码、数据、资源和执行状态信息的操作系统实体。因此,每个进程只能在一个“时间片”内获得CPU的控制权,然后将控制权交回操作系统,操作系统再将CPU交于另一个进程。
进程生成机制除了通过执行可执行程序创建,还可以通过从现有进程中创建。生成一个进程需要精确复制当前进程的内存,包括所有代码和数据。逻辑上看,就像一个新的进程开始在此处执行,从而使得两个进程执行不同的任务。
image
fork()函数是Linux系统创建进程的函数,具有调用一次,返回两次,复制全部内存的特点。也就是说,在代码里面只需要写一行fork(),就会让父进程返回子进程ID,而子进程会返回0,并且子进程会继承父进程的代码,数据和栈。但是fork()的特点是它太重了,需要复制全部的内存,因此多核编程要用线程来替代。
进程生成机制中的两个问题。
image
2.3 线程
线程可以被认为是轻量级进程。线程是一个执行路径,即一个指令序列,可以被操作系统作为整体单元进行管理调度。一个进程可以有多个线程。回顾操作系统,进程是资源分配的基本单位,拥有代码,数据,内存,文件等,而线程是调度执行的基本单位,有自己的栈,寄存器和程序计数器。
主线程:每一个进程(也就是每一个执行起来的可执行文件),都有一个主线程,这个主线程是唯一的,即一个进程只能有一个主线程。当一个可执行程序执行起来的时候,产生一个进程,同时主线程就会跟着这个进程默默启动起来。主线程执行完return后,表示整个进程运行完毕,此时主线程结束运行,进程也结束运行。
线程的创建:线程可以减轻进程机制中的开销,仅需拷贝基本数据,即运行栈。运行栈是不能被多个线程共享的。
image
image
这张图展示了单线程和多线程的内存布局。单线程就是一个寄存器,一个栈,代码,数据,文件共享;多线程就是每个线程都有自己的独立的寄存器和运行栈,不过代码,数据和文件依旧是共享的。也就是多个线程共享进程资源,但是有各自的执行状态。
线程比进程轻,因为只复制栈而不复制代码;多个线程在一个进程里面共享代码和数据,但各自有独立的运行栈。
线程的作用:提高性能、后台任务、异步处理、改进程序结构。
3 共享内存模型
共享内存模型是多线程编程的核心编程模型。前面讲过,进程有代码、数据和文件,这些就是共享内存的内容;线程可以共享进程资源,指的就是共享内存里面的资源;线程有自己的栈和寄存器,也就是共享内存模型里面每个线程自己的私有数据。
线程共享全局数据,但各自拥有私有数据,程序员必须负责保护共享数据的访问,这也是后面所有同步机制,如互斥量等存在的理由。
image
4 下面的一些内容很散,了解即可
image
image
image
image
内核级线程就是后面会讲到的Pthreads线程。
image
image
image
image
image
这一页主要是讲用户级线程和内核级线程如何对应的,主要是一对一对应,Pthread就是一对一。
image
image
image
这一部分的内容对后面的帮助就是,要知道主线程在进程启动,也就是main()启动的时候就启动,对于新线程则要用pthread_create()函数启动,执行完成就调用pthread_exit()结束,主线程退出则整个进程结束,后续写代码会用到这些API。
image
image
image
image
暂时重点理解互斥量即可,其他的属于操作系统的问题了。
image
image
image
image
image
重点是数据分解,也就是不同的线程对不同的数据执行相同的操作。
image
image
重点是Pthread。

http://www.jsqmd.com/news/513181/

相关文章:

  • [算法解析] 装箱问题:从 Next-Fit 到 First-Fit 的近似比分析与实战场景
  • K230 CanMV引脚配置原理:FPIOA与GPIO深度解析
  • Kook Zimage 真实幻想 Turbo 光影效果专题:如何生成逼真的光影变化
  • 2026年废旧设备回收厂家推荐:拆除回收/废铁/变压器/电机回收一站式解决方案 - 品牌推荐官
  • 伏羲天气预报镜像免配置实战:Docker化部署与Gradio界面定制指南
  • 从串口到Modbus:工业通信协议实战与libmodbus库应用解析
  • 立知lychee-rerank-mm在.NET平台的应用:跨模态搜索系统
  • Cesium跨平台开发实战:从Web到Unreal/Unity的3D地理可视化全栈指南
  • Nanbeige 4.1-3B 效果展示:基于Transformer架构的复杂文本生成案例
  • Qwen-Image效果展示:Qwen-VL对建筑设计效果图→空间功能分析→用户需求匹配度评估
  • 避免碰撞的编队控制:分布式线性二次离散时间博弈方法
  • Qwen3-14B-INT4-AWQ破解软件测试面试难题:常见测试用例设计与思维考察
  • VibeVoice实时语音合成:5分钟快速部署,25种音色一键体验
  • MicroPython嵌入式多线程实战:K230-CanMV线程调度与同步详解
  • 从导航App到外卖配送:聊聊GIS算法如何悄悄改变你的日常生活
  • Zynq远程更新程序实战:从emmc到flash的完整方案解析
  • 面试题5:位置编码(Positional Encoding)的作用是什么?绝对、相对位置编码(如RoPE)的区别?
  • Quartus II调用IP核无法生成.vo文件?Modelsim仿真失败的终极解决方案
  • jvm组成
  • Swift-All优化升级:从单机到集群,教你如何提升模型服务稳定性
  • Z世代内容创作神器:图图的嗨丝造相AI镜像,快速产出潮流视觉素材
  • Qwen3-32B医疗领域实践:医学文献摘要与患者问答系统的私有化部署路径
  • 2026年膨化食品设备厂家推荐:膨化食品生产线/膨化食品挤出机专业制造商精选 - 品牌推荐官
  • django基于Python的二手房源信息爬取与分析
  • Pixel Dimension Fissioner环境部署:Mac M2芯片原生运行像素工坊教程
  • Qwen3.5-9B高效混合架构解析:门控Delta网络结构与部署
  • DeerFlow商业场景实战:用AI研究助手提升行业分析与决策效率
  • firefox F12 清空日志
  • Qwen2.5-7B-Instruct显存优化秘籍:防爆显存设置,低配置也能跑大模型
  • 硬件工程师的生存现实:技术能力与职业发展的错位