首页 > 其他分享 >线程和协程

线程和协程

时间:2024-11-28 14:22:32浏览次数:6  
标签:协程 调度 式调度 线程 切换 上下文


线程(Thread):想象线程就像是公司的员工。每个员工都有自己的任务和责任,但他们共享公司的资源(例如办公室、打印机等)。员工(线程)的上下班(开始和结束线程)以及工作调度(线程切换)由公司管理层(操作系统)控制,想想就挺残忍的。
如果公司要新增一个员工或者安排员工之间的工作,这需要管理层的直接参与,也会涉及到较多的人力和物力资源(也就是说,线程的创建和上下文切换成本相对较高)。

协程(Coroutine):现在想象协程就像是在家工作的自由职业者。他们使用自己的电脑和办公设备(拥有自己的堆栈和局部变量),并且自己决定什么时候工作、什么时候休息(编程者控制)。
他们可以随时暂停工作去喝杯咖啡或是散步(yield或等待),然后再回来继续工作。所有这些活动的安排都不需要外部管理层的参与(用户级的调度),并且几乎不需要额外的资源(低成本的任务切换)。

协作式调度:当前线程完全占用CPU时间,除非自己让出时间片,直到运行结束,系统才执行下一个线程。可能出现一个线程一直占有CPU,而其他线程等待。
抢占式调度:操作系统决定下一个占用CPU时间的是哪一个线程,定期的中断当前正在执行的线程,任何一个线程都不能独占。不会因为一个线程而影响整个进程的执行。


协程(Coroutines)的完整定义是“协作式调度的用户态线程”
协作式调度
A用6分钟, 我先用你一会用
B用4分钟
A是6分+B4分=10分

抢占式调度:AB都用打印机
A用2分钟
B用2分钟
A用2分钟
B用2分钟
A用2分钟
A是6分+B4分=10分

假设调度使用相同的时间,但是协程只需要2次调度切换而抢占式调用需要5次调度切换。
A在携程调度下6分钟完成就可以干别的了,但是普通均分调度下要等4分钟+工作6分钟=整体耗时10分钟来完成。


操作系统切换线程上下文的步骤如下所示:
1)保留用户态现场(上下文、寄存器、用户栈等)
2)复制用户态参数,用户栈切到内核栈,进入内核态
3)代码安全检查(内核不信任用户态代码)
4)执行内核态代码
5)复制内核态代码执行结果,回到用户态
6)恢复用户态现场(上下文、寄存器、用户栈等)
操作系统对线程有感知,经常管理,这就是需要耗费性能开销,
但是协程管不着,开销就没那么大,协程在开销上是轻量级的线程,不用处处系统感知管理。


协程不是操作系统的底层特性,系统感知不到它的存在。
它运行在线程里面,通过分时复用线程的方式运行,不会增加线程的数量。
协程也有上下文切换,但是不会切换到内核态去,比线程切换的开销要小很多。
在IO密集型的任务中有着大量的阻塞等待过程,协程采用协作式调度,在IO阻塞的时候让出CPU,当IO就绪后再主动占用CPU,牺牲任务执行的公平性换取吞吐量。

协程和线程的共同点:
都是并发操作,多线程同一时间点只能有一个线程在执行,协程同一时间点只能有一个任务在执行;

协程和线程的不同点:
多线程,是在I/O阻塞时通过切换线程来达到并发的效果,在什么情况下做线程切换是由操作系统来决定的,会造成竞争条件。
协程是用函数切换,开销极小,不通过操作系统调度,没有进程、线程的切换开销。

协程对比线程,在2个方面有影响:
在调度方式上(线程调度采用的调用cpu的方法在调度方式上(线程调度采用的调用cpu的方法)开销更小,
在上下文切换用户态上比线程更自由开销更小。

更简单:
协程用户态协作式调度方式比线程抢占式调度更优。
协程上下文切换比线程上下文系统切换更小。

标签:协程,调度,式调度,线程,切换,上下文
From: https://www.cnblogs.com/adamans/p/18574192

相关文章

  • 消息队列用于线程间通信
    #include<unistd.h>#include<stdio.h>#include<pthread.h>#include<sys/types.h>#include<sys/ipc.h>#include<sys/msg.h>pthread_tpid_1,pid_2;pthread_mutex_tmutex=PTHREAD_MUTEX_INITIALIZER;intmsgid;typedef......
  • 线程池的创建及工作原理和Executor框架
    目录一、什么是线程池:二、创建线程池:三、线程池执行策略:四、如何合理的配置线程池的大小?五、Executor框架:六、Java线程模型:Java线程与操作系统线程的关系:七、ThreadPoolTaskExecutor:⭐八、真实项目的使用详解:九、线程池监控:一、什么是线程池:线程池主要是为了解决......
  • java 多线程传统锁:synchronized,Lock锁
    传统锁:synchronized是内置关键词,无法获取锁的状态Lock锁:类是否获取到锁,需手动释放锁publicclassSaleTicketDem{publicstaticvoidmain(String[]args){Ticket2t=newTicket2();newThread(()->{for(inti=0;i<40;i++){t.sale();;}},"a").start();n......
  • 【高性能组件(1)】手写线程池
    文章目录前言一、线程池介绍1.1为什么需要线程池?1.2线程池的作用1.3线程池的构成二、手写线程池2.1接口设计2.1.1封装原则2.1.2创建线程池的接口2.2数据结构设计2.3线程池线程数量选择2.3.1维持固定数量线程2.3.2线程数量选择2.4具体编码实现2.4.1外部接......
  • 【Linux】多线程(POSIX信号量、线程池、线程安全)
    ......
  • 鸿蒙多线程开发——sendable共享容器
    1、异步锁机制在介绍共享容器之前,先介绍异步锁机制。为了解决多线程并发任务间的数据竞争问题,ArkTS引入了异步锁能力。异步锁可能会被类对象持有,因此为了更方便地在并发实例间获取同一个异步锁对象,AsyncLock对象支持跨线程引用传递。由于ArkTS语言支持异步操作,阻塞锁容易产......
  • 介绍程序、进程与线程和计算机网络体系结构和计算机硬件组成以及计算机网络分类
    程序、进程与线程程序:程序是一组有序的指令,它定义了计算机执行特定任务的步骤。程序通常以源代码的形式存在,需要编译或解释成机器语言,计算机才能执行。程序是静态的,它只是指令和数据的集合,没有执行的概念。进程:进程是程序的执行实例。当程序被加载到内存并开始运行时,它就变......
  • 进程和线程的区别
    一、进程(一)进程的概念进程是指程序的一次执行过程,它具有生命周期,从创建到终止经历了一系列的状态变化。(二)进程的作用进程作为操作系统进行资源分配的基本单位,主要目的是为了实现程序的并发执行,从而提高系统的资源利用效率和处理能力。(三)进程的限制由于进程涉及资源的分配与......
  • 【Linux】线程同步与互斥
    文章目录1.线程互斥1.1进程线程间的互斥相关背景概念1.2互斥量mutex1.3相关操作1.4互斥量实现原理1.5互斥量的封装2.线程同步2.1条件变量2.2生产者消费者模型2.3基于BlockingQueue的生产者消费者模型2.4信号量2.5基于环形队列的生产消费模型3.线程池3.1......
  • Java进阶六-多线程
    一多线程相关概念进程(Process):进程是程序的基本执行实体。进程是操作系统分配资源的基本单位。每个进程都有自己的内存空间、代码段、数据段等。进程之间相互独立,一个进程的崩溃不会影响其他进程。进程是程序的基本执行实体。线程(Thread): 应用软件中相互独立,可以......