进程、线程、协程

164 阅读6分钟

1. 并行与并发

  • 并发:在操作系统中,某一时间段,几个程序在同一个CPU上运行,但在任意一个时间点上,只有一个程序在CPU上运行

    • 当有多个线程时,如果系统只有一个CPU,那么CPU不可能真正同时进行多个线程,CPU的运行时间会被划分成若干个时间段,每个时间段分配给各个线程去执行,一个时间段里某个线程运行时,其他线程处于挂起状态,这就是并发。并发解决了程序排队等待的问题,如果一个程序发生阻塞,其他程序仍然可以正常执行。
  • 并行:当操作系统有多个CPU时,一个CPU处理A线程,另一个CPU处理B线程,两个线程互相不抢占CPU资源,可以同时进行,这种方式成为并行

  • 区别:

    • 并发只是在宏观上给人感觉有多个程序在同时运行,但在实际的单CPU系统中,每一时刻只有一个程序在运行,微观上这些程序是分时交替执行
    • 在多CPU系统中,将这些并发执行的程序分配到不同的CPU上处理,每个CPU用来处理一个程序,这样多个程序便可以实现同时执行
  • 举例:

    • 你吃饭吃到一半,电话来了,你一直到吃完了以后才去接,这就说明你不支持并发也不支持并行。
    • 你吃饭吃到一半,电话来了,你停了下来接了电话,接完后继续吃饭,这说明你支持并发。
    • 你吃饭吃到一半,电话来了,你一边打电话一边吃饭,这说明你支持并行。
  • 总结:

    • 并发的关键是你有处理多个任务的能力,不一定要同时。并行的关键是你有同时处理多个任务的能力。所以我认为它们最关键的点就是:是否是同时

2. 进程

  • 介绍:一个进程好比是一个程序,它是 资源分配的最小单位 。同一时刻执行的进程数不会超过核心数。不过如果问单核CPU能否运行多进程?答案又是肯定的。单核CPU也可以运行多进程,只不过不是同时的,而是极快地在进程间来回切换实现的多进程。举个简单的例子,就算是十年前的单核CPU的电脑,也可以聊QQ的同时看视频
  • 描述:电脑中有许多进程需要处于同时开启的状态,而利用CPU在进程间的快速切换,可以实现「同时」运行多个程序。而进程切换则意味着需要保留进程切换前的状态,以备切换回去的时候能够继续接着工作。所以进程拥有自己的地址空间,全局变量,文件描述符,各种硬件等等资源。操作系统通过调度CPU去执行进程的记录、回复、切换等等
  • 进程之间通信
    • 管道pipe
      • 管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道
      • 只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程)
      • 数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据,数据取了就没了。
    • 命名管道FIFO
      • 以有名管道的文件形式存在于文件系统中,这样即使与有名管道的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过有名管道相互通信,遵循先进先出规则。
      • 名字存在在文件系统中,数据存放在内存中。
    • 消息队列MessageQueue
      • 消息队列是存放在内核中的消息链表,每个消息队列由消息队列标识符表示
      • 与管道不同的是消息队列存放在内核中,只有在内核重启(即,操作系统重启)或者显示地删除一个消息队列时,该消息队列才会被真正的删除。
      • 另外与管道不同的是,消息队列在某个进程往一个队列写入消息之前,并不需要另外某个进程在该队列上等待消息的到达
    • 共享存储SharedMemory
      • 使得多个进程可以直接读写同一块内存空间,是最快的可用进程通信(IPC)形式。是针对其他通信机制运行效率较低而设计的
      • 为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将其映射到自己的私有地址空间。进程就可以直接读写这一块内存而不需要进行数据的拷贝,从而大大提高效率
      • 由于多个进程共享一段内存,因此需要依靠某种同步机制(如信号量)来达到进程间的同步及互斥
    • 信号量Semaphore : 信号量是一个计数器,用于多进程对共享数据的访问,信号量的意图在于进程间同步
    • 套接字Socket:套接字是一种通信机制,凭借这种机制,客户/服务器(即要进行通信的进程)系统的开发工作既可以在本地单机上进行,也可以跨网络进行。也就是说它可以让不在同一台计算机但通过网络连接计算机上的进程进行通信
      • 套接字的特性由3个属性确定,它们分别是:域、端口号、协议类型
    • 信号 ( sinal ):信号是Linux系统中用于进程间互相通信或者操作的一种机制,信号可以在任何时候发给某一进程,而无需知道该进程的状态

3. 线程

  • 介绍:线程是基于进程中的,一个进程中有许多个线程,线程是 程序执行过程中的最小单元
  • 描述:线程能够共享进程的大部分资源,并参与CPU的调度。意味着它能够在进程间进行切换,实现并发,线程和线程之间由于某些资源是独占的,会导致锁的问题。例如Python的GIL多线程锁