首页 > 系统相关 >进程 线程 协程 简单介绍

进程 线程 协程 简单介绍

时间:2023-09-14 15:15:43浏览次数:43  
标签:协程 用户 线程 内核 进程 CPU

一、进程

1.1 进程可看做是正在执行的程序

进程需要一定的资源(如 CPU、时间、内存、文件和 I/O 设备)来完成其任务。 这些资源在创建进程或者执行进程时被分配。

1.2 进程的组成有:PCB、程序段、数据段。

  • PCB(进程控制块,process control block): 保存进程运行期间相关的数据,是进程存在的唯一标志。
  • 程序段: 能被进程调度程序调度到 CPU 运行的程序的代码段。
  • 数据段: 存储程序运行期间的相关数据,可以是原始数据也可以是相关结果。

1.3 进程在执行时会改变状态,进程的状态有 5 种:

  • 创建:进程正在被创建。
  • 运行:指令正在被执行。
  • 等待:阻塞,进程等待某个事件的发生(如 I/O 完成或收到信号)。
  • 就绪:进程等待分配处理器。
  • 终止:进程完成执行

二、线程

2.1 进程是系统资源分配基本单位,线程是处理器(CPU)调度的基本单位。

通常情况下,一个进程里面只有一个控制流,但是在现代的系统中,为了充分的利用系统资源,一个进程实际上是可以有多个称为线程的执行单元的,每一个线程都运行在进程的上下文(进程地址空间)中,一个进程中的线程除了自己独有的数据之外,都是共享同一个进程里面的数据的,故在多线程之间共享数据比在多进程之间共享数据容易很多。进程在实现上有分为内核级线程和用户级线程,以及内核级和用户级混合的线程。在Linux系统中,是没有真正意义上的线程的,它将线程的实现为一个轻量级的进程,其通过在进程之间共享数据的方式来实现线程的。相对于Linux系统的其他系统,比如windows系统就实现了区别于进程的线程。

2.2 要理解线程调度的两种方式:

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

操作系统的核心是内核(kernel),它独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。有些CPU 的指令是非常危险的,一旦用错可能导致系统崩溃。如果所有的程序都可以任意使用这些指令,那么系统崩溃的概率将大大增加。为了保证内核的安全,操作系统一般都禁止用户进程直接操作内核。具体的实现方式是将虚拟内存空间划分为两部分,一部分为内核空间,另一部分为用户空间。当进程运行在内核空间时就处于内核态,进程运行在用户空间时则处于用户态。

无论是进程还是线程,它们的上下文切换和"内核态、用户态"没有直接的关系。比如只要需要系统调用,即使不做任何切换,都需要进入内核态。举个例子:一个线程调用函数在屏幕上打印 hello world,就已经进入了内核态了,因为打印字符的功能是由内核程序提供的。总的来说,应用程序通常运行在用户态,遇到下列三种情况会切换到内核态:

系统调用:创建和调度线程、加锁解锁等等。
异常事件:发生不可知的异常时切换到内核态,以执行相关的异常事件。
设备中断:如果外围设备完成了用户请求,比如硬盘读写操作,就会给CPU发送中断信号。CPU会转去处理中断事件,切换到内核态。
线程的代码在用户态运行,而调度是在内核态运行的。

2.3 操作系统切换线程上下文的步骤如下所示:

1)保留用户态现场(上下文、寄存器、用户栈等)
2)复制用户态参数,用户栈切到内核栈,进入内核态
3)代码安全检查(内核不信任用户态代码)
4)执行内核态代码
5)复制内核态代码执行结果,回到用户态
6)恢复用户态现场(上下文、寄存器、用户栈等)

三、协程

3.1 协程:一般称协程为轻量级线程。

对于操作系统来说,内核只“认识”进程和线程,对于协程的存在,内核是不知道的,需要用户负责协程的创建、调度和销毁,因此,协程又被称为用户级线程。

3.2 协程的性质:

  • 协程是一种用户态的轻量级线程,协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方(一般是自定义的数据结构中),在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。
  • 对操作系统而言,线程是最小的执行单元,进程是最小的资源管理单元。无论是进程还是线程,都是由操作系统所管理的。
  • 协程不是被操作系统内核所管理的,而是完全由程序所控制,也就是在用户态执行。这样带来的好处是性能大幅度的提升,因为不会像线程切换那样消耗资源。
  • 协程既不是进程也不是线程,协程仅仅是一个特殊的函数,协程它进程和进程不是一个维度的。
  • 一个进程可以包含多个线程,一个线程可以包含多个协程。
  • 一个线程内的多个协程虽然可以切换,但是多个协程是串行执行的,只能在一个线程内运行,没法利用 CPU 多核能力。
  • 协程与进程一样,切换是存在上下文切换问题的。

资料:
http://m.rookiew.com/mirrors/4039.html
https://zhuanlan.zhihu.com/p/569273620?utm_id=0
https://zhuanlan.zhihu.com/p/446993465
https://blog.csdn.net/m0_37851345/article/details/119023413

标签:协程,用户,线程,内核,进程,CPU
From: https://www.cnblogs.com/xiaohaigegede/p/17702372.html

相关文章

  • 支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用
    欢迎访问我的GitHub这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos本篇概览本篇是《支持JDK19虚拟线程的web框架》系列的中篇,前文咱们体验了有虚拟线程支持的web服务,经过测试,发现性能上它与其他两种常见web架构并无明显区别,既然如此,还有......
  • 并发编程——进程
    process——进程一.multiprocessing模块介绍python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程。Python提供了multiprocessing。multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如......
  • 僵尸进程zombie
    #2:定位僵尸进程ID。ps-A-ostat,ppid,pid,cmd|grep-e"^[Zz]"ps-ef|grep"defunct"#3.查看服务结束。......
  • 记录一个python多线程的错误写法
    直接先上错误代码:importmultiprocessingdeffirst_way():init=3defprocess_function(item):result=item*initreturnresultdata=[1,2,3,4,5,6,7,8,9,10]pool=multiprocessing.Pool(processes=4)#创建一个......
  • volatile关键字,使变量在多个线程之间可见
    在多线程中继承Thread类和实现runnable接口的别并不大,但是,如果是需要继承Thread之外的其他接口,就可以使用实现runnable接口的方式。测试类:publicclassPrintString{privatebooleanisContinuePrint=true;publicbooleanisContinuePrint(){returnis......
  • 进程管理2(Ubuntu)
    一:top命令  ps命令只显示某一时刻的信息,是静态的,top命令可以实时的显示系统中各个进程的资源占用情况,是动态的。格式:top[选项] top的选项如图所示:选项说明-d后面指定秒数,表示进程界面的时间间隔,默认时间是秒-n后面指定次数,表示输出信息更新的次数-p指定进程的PID查看检测结果 ......
  • 第十八章 多线程
    18.1基本概念18.1.1程序和进程的概念程序-数据结构+算法,主要指存放在硬盘上的可执行文件。进程-主要指运行在内存中的可执行文件。目前主流的操作系统都支持多进程,为了让操作系统同时可以执行多个任务,但进程是重量级的,也就是新建一个进程会消耗CPU和内存空间等系统资......
  • Android 编译线程爆了, gradle 内存 OOM 解决之路
    本文首发我的微信公众号徐公,收录于Github·AndroidGuide,这里有Android进阶成长知识体系,希望我们能够一起学习进步,关注公众号徐公,5年中大厂程序员,一起建立核心竞争力背景最近我们项目在编译的时候,编译多次之后,有挺多人反馈会出现OOM的,在项目的根目录下面会出现hs_err_......
  • 线程池------小记
    1、线程池的产生背景1、线程是一种系统资源,每创建一个新的线程都会占用一定的内存。如果是高并发的情况下,短时间生成了很多任务,如果为每个任务都创建一个新的线程,对内存的占用是相当大的,甚至有可能出现内存内存溢出。2、同时线程也不是创建的越多越好,在cpu核数的限制下,当需要大量......
  • play如何创建多线程任务
    应用场景:需要多线程同时操作数据库,进行insrt操作准备:1、要将数据拆分开来,具备唯一的id主键,在insert之前判断是否已经存在数据库2、创建一个线程类publicclassBidInfoThreadextendsThread{privateintdata;publicBidInfoThread(intdata){this.data=d......