进程,线程和协程有什么区别和联系,进程和线程和协程的区别
什么是进程和线程?
有一定基础的朋友一定都懂流程和线程。
流程是怎样的?
坦率地说,进程是应用程序的启动实例。比如我们运行一个游戏,打开一个软件,就启动了一个进程。
拥有进程代码和开放的文件资源、数据资源和独立的内存空间。
有人认为,要提高CPU利用率,可以开多个进程,但如果开多个进程,进程间通信就麻烦了(进程间的地址空间是独立的,需要通过管道等其他方式解决)。
相反,线程之间可以实现数据共享,因为线程使用相同的地址空间。
什么是线程?
线程也称为轻量级进程,是CPU调度的最小单位。线程从属于进程,是程序的实际执行者。
一个进程至少包含一个主线程,或者可以有多个子线程。
多个线程共享自己进程的资源,每个线程都有自己的独占资源和自己的堆栈空间。
线程间通信主要是通过共享内存,上下文切换快,资源开销低,但相比不稳定的进程,容易丢失数据。
线程和进程一样,由操作系统的调度程序统一调度。线程本身的数据结构需要占用内存,频繁的创建和销毁线程会增加系统的压力。另外,如果线程太多,系统调度的开销也会增加。
基于上述情况,提出了线程池解决方案,在初始化时批量创建线程,然后用户通过队列提交业务逻辑,线程池中的线程消耗逻辑,可以减少运行过程中创建和销毁线程的成本,但调度的成本仍然存在。
有人做了很好的总结:
对于操作系统来说,线程是最小的执行单元,进程是最小的资源管理单元。
在多核场景下,如果是I/O密集型场景,即使打开多个线程进行处理,也未必能提高CPU利用率,反而会增加线程切换的开销。此外,如果多线程之间存在临界区或共享数据,同步的开销也不能忽略。
谢成正好可以解决上述相关问题。
这时候我们的主角谢承就要上台了。
协同进程,英文Coroutines,是一个比线程更轻量级的存在。正如一个进程可以有多个线程一样,一个线程也可以有多个协程。协调过程的调度完全由用户控制。协同进程有自己的寄存器上下文和堆栈。当协调调度切换时,寄存器上下文和堆栈被保存到其他地方,当它被切换回来时,先前保存的寄存器上下文和堆栈被恢复。栈的直接操作基本没有内核切换开销,全局变量可以不加锁访问,所以上下文切换非常快。协程和线程的主要区别是不再由内核调度,而是交给程序本身,线程再把自己交给内核调度,这样就不难理解golang中调度器的存在了。
教练定义:教练是一个轻量级的线程。
多个协程可以在一个用户线程上运行,这提高了单核的利用率。与进程或线程不同,协程可以让系统负责相关的调度工作。协程在一个线程中,系统不知道,所以如果一个协程需要在线程中被阻塞,需要手动调度。
教练是用户态的轻量级线程,其调度完全由用户控制。一个线程可以有多个协程,协程不是由操作系统内核管理,而是完全由程序控制。与其让操作系统来调度,不如我自己来。这是协同过程。
很难在用户线程上实现协同程序。原理类似于调度器根据条件的变化不断调用每个协程的回调机制,但前提是大家都在同一个用户线程里。需要注意的是,一旦一个协同学被屏蔽,其他协同学就跑不了了。因此,我们应该处理协调过程。
最重要的是,协程不是由操作系统内核管理,而是完全由程序控制(即在用户态执行)。
这样做的好处是性能大大提升,不会像线程切换一样消耗资源。
这段代码非常简单,即使是没用过python的朋友也应该能基本看懂。
该代码创建了一个名为consumer的协程,它在主线程中产生数据,并在协程中消费数据。
Yield是python中的语法。当协程执行到yield关键字时,它将在那一行暂停。当主线程调用send方法发送数据时,协程将接收数据并继续执行。
然而,yield停止进程和线程阻塞之间有一个基本的区别。进程的暂停完全由程序控制,线程的阻塞状态由操作系统内核切换。
所以协程的开销远远小于线程。
协同过程的应用
协同学应用过哪些编程语言?举几个栗子吧:
卢阿语
Lua从5.0版本开始使用协程,通过扩展库协程来实现。
Python语言
就像刚才写的代码例子一样,python可以通过yield/send实现协同。在python 3.5之后,async/await成为了更好的选择。
Go语言
Go语言对于协程的实现非常强大和简洁,它可以轻松地创建数百个协程并并发执行。
java 3d
如上所述,Java语言没有协同学的原生支持,但是一些开源框架模拟了协同学的功能。感兴趣的伙伴可以看看Kilim框架的源代码:
摘要:多进程似乎可以提高CPU的利用率,尤其是对于I/O密集型操作。不管是多核还是单核,开放多个进程势必有效提高CPU的利用率。多线程可以共享同一进程地址空间中的资源。为了降低创建和销毁线程的成本,线程池的概念再次出现。最后,为了提高用户线程的最大利用效率,提出了协程的概念。
通信模式:
线程的生命周期
创建:从线程创建到cpu执行的阶段。
就绪:线程有各种执行条件,一旦获取cpu就可以执行。
Run:表示线程正在让cpu运行。
阻塞:是指一个线程在执行过程中被什么东西阻塞了,处于挂起状态。被阻塞的线程不会竞争cpu。
终止:线程执行完毕后,线程所占用的资源将被释放。
进程调度算法
转载请联系作者授权,否则将追究法律责任。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。