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

[Java进阶] 并发编程之进程、线程和协程

并发编程系列文章

[Java进阶] 并发编程入门介绍

目录

定义与概念

进程

状态

生命周期管理

线程

状态

生命周期管理

协程

状态

生命周期管理

进程、线程、协程对比

资源开销

上下文切换

并行与并发

隔离性

编程复杂度


定义与概念

  • 进程:进程是程序在执行过程中分配的基本单位,是程序的一次动态执行过程。每个进程都有独立的内存空间和系统资源,通过进程间通信(IPC Inter-Process Communication)进行通信。
  • 线程:线程是进程中的一个执行路径或执行单元,是CPU调度的最小单位。线程共享进程的资源,因此线程间通信相对简单且高效。
  • 协程:协程是一种用户态的轻量级线程,其调度和切换完全由用户控制。协程不是由操作系统内核管理,而是由程序所控制,适合处理大量的I/O密集型任务。

进程

状态

  • 新建(New):进程正在被创建,但尚未准备好执行。操作系统分配必要的资源,如内存、文件描述符等,并创建进程控制块(PCB)。
  • 就绪(Ready):进程已经准备好执行,等待CPU资源。进程在就绪队列中等待调度器分配CPU时间。
  • 运行(Running):进程正在CPU上执行。操作系统调度器选择一个就绪状态的进程,将其状态变为运行,并分配CPU资源。
  • 阻塞(Blocked):进程因为等待某个事件(如I/O操作完成、信号量等)而暂停执行。进程从运行状态变为阻塞状态,释放CPU资源,直到等待的事件发生。
  • 终止(Terminated):进程执行完毕或因错误而终止。操作系统释放该进程占用的资源,删除其PCB。

生命周期管理

  • 创建
    • 系统调用:用户或系统通过系统调用(如fork()exec())请求创建新进程。
    • 资源分配:操作系统分配必要的资源,如内存、文件描述符等。
    • 进程控制块(PCB):创建进程控制块(PCB),记录进程的状态、优先级、内存分配情况等信息。
  • 调度
    • 调度算法:操作系统使用调度算法(如时间片轮转、优先级调度、最短作业优先等)选择下一个要执行的进程。
    • 调度器:调度器负责将CPU分配给选中的进程,并保存当前进程的上下文(寄存器状态、程序计数器等)到PCB。
  • 上下文切换
    • 保存上下文:当当前进程因某种原因(如时间片用完、等待I/O操作、被更高优先级的进程抢占等)需要暂停执行时,操作系统会进行进程切换。
    • 更新状态:将当前进程的状态从“运行”改为“就绪”或“阻塞”。
    • 选择新进程:根据调度算法选择下一个要执行的进程。
    • 恢复上下文:从新进程的PCB中恢复其上下文。
    • 切换控制权:修改程序状态字(PSW),将控制权交给新的进程。
  • 终止
    • 执行完毕或错误:进程执行完毕或因错误而终止。
    • 资源释放:操作系统释放该进程占用的资源,删除其PCB。

线程

状态

  • 新建(New):线程正在被创建,但尚未准备好执行。操作系统分配必要的资源,如栈空间,并创建线程控制块(TCB)。
  • 就绪(Ready):线程已经准备好执行,等待CPU资源。线程在就绪队列中等待调度器分配CPU时间。
  • 运行(Running):线程正在CPU上执行。操作系统调度器选择一个就绪状态的线程,将其状态变为运行,并分配CPU资源。
  • 阻塞(Blocked):线程因为等待某个事件(如I/O操作完成、信号量等)而暂停执行。线程从运行状态变为阻塞状态,释放CPU资源,直到等待的事件发生。
  • 终止(Terminated):线程执行完毕或因错误而终止。操作系统释放该线程占用的资源,删除其TCB。

生命周期管理

  • 创建
    • 系统调用:在已存在的进程中通过系统调用(如pthread_create())创建新线程。
    • 资源分配:操作系统分配线程所需的少量资源(如栈空间)。
    • 线程控制块(TCB):创建线程控制块(TCB),记录线程的状态、优先级等信息到TCB。
  • 调度
    • 调度算法:操作系统使用线程调度算法(如时间片轮转、优先级调度等)选择下一个要执行的线程。
    • 调度器:调度器负责将CPU分配给选中的线程,并保存当前线程的上下文。
  • 上下文切换
    • 保存上下文:当当前线程因某种原因(如时间片用完、等待I/O操作、被更高优先级的线程抢占等)需要暂停执行时,操作系统会进行线程切换。
    • 更新状态:将当前线程的状态从“运行”改为“就绪”或“阻塞”。
    • 选择新线程:根据调度算法选择下一个要执行的线程。
    • 恢复上下文:从新线程的TCB中恢复其上下文。
    • 切换控制权:修改程序状态字(PSW),将控制权交给新的线程。
  • 终止
    • 执行完毕或错误:线程执行完毕或因错误而终止。
    • 资源释放:操作系统释放该线程占用的资源,删除其TCB。

协程

状态

  • 新建(New):协程正在被创建,但尚未准备好执行。应用程序或库分配必要的资源,如栈空间,并创建协程控制块(CCB)。
  • 就绪(Ready):协程已经准备好执行,等待调度。协程在就绪队列中等待调度器分配执行机会。
  • 运行(Running):协程正在执行。调度器选择一个就绪状态的协程,将其状态变为运行,并分配执行机会。
  • 挂起(Suspended):协程因为等待某个事件(如I/O操作完成、其他协程的通知等)而暂停执行。协程从运行状态变为挂起状态,释放执行资源,直到等待的事件发生。
  • 终止(Terminated):协程执行完毕或因错误而终止。应用程序或库释放该协程占用的资源,删除其CCB。

生命周期管理

  • 创建
    • 库函数:应用程序或库通过特定的库函数(如Python的asyncio.create_task()、C++的std::coroutine_handle)创建新协程。
    • 资源分配:应用程序或库分配必要的资源(如栈空间)。
    • 协程控制块(CCB):创建协程控制块(CCB),记录协程的状态、栈指针等信息到CCB。
  • 调度
    • 调度器:使用协程调度器(如Python的asyncio、C++的std::coroutine_handle)选择下一个要执行的协程。
    • 调度算法:调度器通常使用简单的调度算法,如基于事件循环的调度。
  • 上下文切换
    • 保存上下文:当当前协程因某种原因(如等待I/O操作、其他协程的通知等)需要暂停执行时,应用程序或库会进行协程切换。
    • 更新状态:将当前协程的状态从“运行”改为“挂起”。
    • 选择新协程:根据调度算法选择下一个要执行的协程。
    • 恢复上下文:从新协程的CCB中恢复其上下文。
    • 切换控制权:修改程序状态字(PSW),将控制权交给新的协程。注意,协程的上下文切换完全在用户态进行,不涉及内核态和用户态的转换。
  • 终止
    • 执行完毕或错误:协程执行完毕或因错误而终止。
    • 资源释放:应用程序或库释放该协程占用的资源,删除其CCB。

进程、线程、协程对比

下面将从资源开销、上下文切换、并行与并发、隔离性和编程复杂度五个方面全面对比进程、线程和协程。

资源开销

  • 进程:由于每个进程都有独立的内存空间和系统资源,因此创建和销毁进程的开销较大。
  • 线程:线程共享进程的资源,因此创建和销毁线程的开销相对较小。但仍需操作系统进行调度和上下文切换。
  • 协程:协程的创建和销毁开销极小,通常仅涉及函数调用和栈空间分配。协程的调度和切换也完全在用户态进行,因此开销极低。

上下文切换

  • 进程:进程上下文切换涉及内核态和用户态的转换,包括切换页表、内核栈等,因此开销较大。
  • 线程:如果线程属于不同的进程,同样涉及内核态和用户态的转换。如果线程属于同一进程,则内核态转换的开销相对较小,但仍需在内核中完成上下文切换。
  • 协程:协程的上下文切换完全在用户态进行,不涉及内核态切换,因此开销最小。

并行与并发

  • 进程:支持真正的并行运行,多个进程可以在多核CPU上同时执行。
  • 线程:同样支持真正的并行,多个线程可以在多核CPU上并行执行。但共享进程资源,可能引发竞争条件。
  • 协程:协程本质上是并发的,而非并行。因为协程在单个线程内运行,因此无法利用多核CPU的并行能力。

隔离性

  • 进程:进程之间有独立的内存地址空间、文件描述符等资源,彼此完全隔离,适合需要强隔离的任务。
  • 线程:同一进程内的线程共享地址空间、全局变量和文件描述符,因此线程之间资源隔离较弱,容易出现数据竞争。
  • 协程:协程共享同一线程的所有资源,同一线程内的协程没有隔离。但因为协程在用户态中切换,通常不会与其他协程并发执行。

编程复杂度

  • 进程:编写多进程程序较为复杂,特别是在进程间通信(IPC)时需要考虑复杂的机制。
  • 线程:多线程程序编写也较为复杂,需处理同步和互斥问题,以防止数据竞争。
  • 协程:协程编写相对简单,特别是在异步框架中,代码结构更加清晰。但需要注意手动调度和避免阻塞操作。

http://www.mrgr.cn/news/58548.html

相关文章:

  • Cesium for UE-04-一些说明
  • 【STM32 ADC】
  • PyTorch介绍以及实战项目示例
  • excel 表格中url转图片
  • 全能大模型GPT-4o体验和接入教程
  • C#,自动驾驶技术,ASAM OpenDRIVE BS 1.8.0 规范摘要与C# .NET Parser
  • 23种设计模式
  • Vue3 + TypeScript 实现 iframe 嵌入与通信的完整指南以及全屏弹窗方案
  • 动态规划-子序列问题——376.摆动序列
  • 青训营 X 豆包MarsCode 技术训练营--最大矩形面积问题
  • MATLAB锂电概率分布模型
  • 微积分复习笔记 Calculus Volume 1 - 3.7 Derivatives of Inverse Functions
  • 学习webservice的心得
  • TinTin Web3 动态精选:Vitalik 探讨以太坊协议,Solana ETN 开启质押功能
  • Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks
  • Openpyxl--学习记录
  • 标准数字隔离器主要特性和应用---腾恩科技
  • 盘点双十一最值得买的好物有哪些?盘点2024双十一超值好物推荐
  • CTF-RE 从0到N: 重新定义ida识别错误的变量
  • Java基础题:搬砖
  • 将接近感应添加到您的下一个嵌入式设计中
  • Kubernetes高可用方案
  • shell编程实例1—猜数字游戏
  • 《中安未来护照阅读器:边检行业的高效利器》
  • springboot小区物业报修管理系统-计算机设计毕业源码03418
  • ECharts系列:图表中显示点,点与点之间不连线