当前位置:首页 > 运维 > 正文内容

进程、线程和协程三者之间的区别和联系

phpmianshi8年前 (2013-04-16)运维443

一、进程、线程、协程

1,进程

    进程,直观点说,保存在硬盘上的程序运行以后,会在内存空间里形成一个独立的内存体,这个内存体有自己独立的地址空间,有自己的堆,上级挂靠单位是操作系统。操作系统会以进程为单位,分配系统资源(CPU时间片、内存等资源),进程是资源分配的最小单位

2,线程(thread)(内核级线程

    线程,有时被称为轻量级进程(Lightweight Process,LWP),是操作系统调度(CPU调度)执行的最小单位

3,协程(用户级线程)

    协程是一种用户态的轻量级线程,又称微线程。协程调度完全由用户控制,相当于子程序。


4,区别

  1、资源方面:进程间相互独立,同一进程的各线程间共享。某进程内的线程在其他进程不可见

  2、通信:进程间通信IPC,进程间可以直接读写进程数据段进行通信——需要进程同步和互斥手段辅助,以保证数据的一致性,线程通信主要通过共享内存

  3、调度和切换:线程上下文切换比进程上下文切换要快的多

  4、对于 进程线程,都是有内核进行调度,有 CPU 时间片的概念,进行 抢占式调度(有多种调度算法),对于 协程(用户级线程),这是对内核透明的,是由用户程序自己控制,通常只能进行 协作式调度,需要协程自己主动把控制权转让出去之后,其他协程才能被执行到。


进程优点:

    1. 进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响

进程缺点:

  1. 在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。多进程的程序要比多线程的程序健壮,但在进程创建、切换、撤销时,耗费资源较大,效率要差一些。

  2. 进程间通信(IPC)较为复杂和耗时


线程优点:

1.线程的出现是为了减少任务切换的消耗,提高系统的并发性,实现让一个进程也能执行多个任务

线程缺点:

1.线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个进程死掉就等于所有的线程死掉

2.线程没有自己的系统资源,只有运行时不可缺少的资源,但是同一进程的各线程可以共享进程所拥有的系统资源。对于某些独占资源存在锁机制,处理不当会出现死锁。


协程优点:

1.协程执行效率高。因为子程序切换不是线程切换,由程序自身控制,避免了陷入内核级别的上下文切换造成的性能损失,进而突破了线程在IO上的性能瓶颈。

2.协程不需要多线程的锁机制。在协程中控制共享资源不加锁,只需要判断状态就好,所以执行效率比多线程高很多。


5.场景

多进程:

密集CPU任务,需要重复利用CPU多核资源(大量的并行计算)


多线程:

密集IO任务(网络IO,磁盘IO,数据库IO)


协程:

当程序中存在大量不需要CPU的操作时


最高效的组合:利用多核CPU最简单的方法是多进程+协程,既充分利用多核,又充分发挥协程的高效率,可获得极高的性能


6.进程/线程之间的亲缘性
  

亲缘性的意思是进程/线程只在某个cpu上运行(多核系统),比如:

使用CPU亲缘性的好处:设置CPU亲缘性是为了防止进程/线程在CPU的核上频繁切换,从而避免因切换带来的CPU的L1/L2 cache失效,cache失效会降低程序的性能。


二、小结


核心只有一个,线程是操作系统调度,协程是用户态调度。协程不必须是语言集成,例如C语言可以用setjmp/longjmp实现,也可以自己通过改变esp指针换栈实现协程。 协程本身跟高吞吐没任何关系,基于io多路复用+回调就可以实现高并发和高吞吐。引入协程是为了将回调逻辑变成线性同步逻辑。


版权声明:本文由PHP面试资料网发布,如需转载请注明出处。
分享给朋友:

相关文章

linux中iptables防火墙详解

1、iptables入门简介Netfilter/Iptables(以下简称Iptables)是unix/linux自带的一款优秀且开放源代码的完全自由的基于包过滤的防火墙工具,主要工作在OSI七层的二...

linux中流量监控工具iftop详解

linux中流量监控工具iftop详解

要查看实时的网络流量,监控TCP/IP连接等,则可以使用iftop。一、iftop是什么?iftop是类似于top的实时流量监控工具。官方网站:http://www.ex-parrot.com/~pd...

彻底弄懂502/503/504(php-fpm+nginx)亲测可用

环境 php7.3.5 + nginx1.16.0相信大家都遇到过50X的问题,网上也看了很多文章,总是各种不对,所以今天咱们详解各种出现50X的情况和原因502:Bad Gateway &...

Nginx中last和break redirect和permanent区别和联系

一.last & break    (1)last 和 break 当出现在location 之外时,两者的作用是一致的没有任何差异。注意一点就是,他们会跳过所有的在他们之...


1、应用程序中调用read() 方法,这里会涉及到一次上下文切换(用户态->内核态),底层采用DMA(direct memory access)读取磁盘的文件,并把内容存储到内核地址空间的读取缓存区。

操作系统检测到进程向I/O设备发起请求后就暂停进程的运行,怎么暂停运行呢?

很简单:只需要记录下当前进程的运行状态并把CPU的PC寄存器指向其它进程的指令就可以了。
进程有暂停就会有继续执行,因此操作系统必须保存被暂停的进程以备后续继续执行,显然我们可以用队列来保存被暂停执行的进程。

注意:现代磁盘向内存copy数据时无需借助CPU的帮助,这就是所谓的DMA(Direct Memory Access)。

实际上:操作系统中除了有阻塞队列之外也有就绪队列,所谓就绪队列是指队列里的进程准备就绪可以被CPU执行了。
你可能会问为什么不直接执行非要有个就绪队列呢?

答案很简单:那就是僧多粥少,在即使只有1个核的机器上也可以创建出成千上万个进程,CPU不可能同时执行这么多的进程,因此必然存在这样的进程,即使其一切准备就绪也不能被分配到计算资源,这样的进程就被放到了就绪队列。

当进程A被暂停执行后CPU是不可以闲下来的,因为就绪队列中还有嗷嗷待哺的进程B,这时操作系统开始在就绪队列中找下一个可以执行的进程,也就是这里的进程B。
此时操作系统将进程B从就绪队列中取出,找出进程B被暂停时执行到的机器指令的位置,然后将CPU的PC寄存器指向该位置,这样进程B就开始运行啦。

此后磁盘终于将全部数据都copy到了进程A的内存中,这时磁盘通知操作系统任务完成啦,你可能会问怎么通知呢?这就是中断
操作系统接收到磁盘中断后发现数据copy完毕,进程A重新获得继续运行的资格,这时操作系统小心翼翼的把进程A从阻塞队列放到了就绪队列当中。

注意:从前面关于就绪状态的讨论中我们知道,操作系统是不会直接运行进程A的,进程A必须被放到就绪队列中等待,这样对大家都公平。

此后进程B继续执行,进程A继续等待,进程B执行了一会儿后操作系统认为进程B执行的时间够长了,因此把进程B放到就绪队列,把进程A取出并继续执行。

注意:操作系统把进程B放到的是就绪队列,因此进程B被暂停运行仅仅是因为时间片到了而不是因为发起I/O请求被阻塞。

进程A继续执行,此时buff中已经装满了想要的数据,进程A就这样愉快的运行下去了,就好像从来没有被暂停过一样


2、由于应用程序无法读取内核地址空间的数据,如果应用程序要操作这些数据,必须把这些内容从读取缓冲区拷贝到用户缓冲区。这个时候,read() 调用返回,且引发一次上下文切换(内核态->用户态),现在数据已经被拷贝到了用户地址空间缓冲区,这时,如果有需要,应用程序可以操作修改这些内容。

3、我们最终目的是把这个文件内容通过Socket传到另一个服务中,调用Socket的send()方法,这里又涉及到一次上下文切换(用户态->内核态),同时,文件内容被进行第三次拷贝,被再次拷贝到内核地址空间缓冲区,但是这次的缓冲区与目标套接字相关联,与读取缓冲区没有半点关系。

4、send()调用返回,引发第四次的上下文切换,同时进行第四次的数据拷贝,通过DMA把数据从目标套接字相关的缓存区传到协议引擎进行发送。

"在整个过程中,过程1和4是由DMA负责,并不会消耗CPU,只有过程2和3的拷贝需要CPU参与


如果在应用程序中,不需要操作内容,过程2和3就是多余的,如果可以直接把内核态读取缓存冲区数据直接拷贝到套接字相关的缓存区,是不是可以达到优化的目的?

Linux中nio的实现原理

我们上一篇文章 《linux中netstat和ss命令详解》中提到了nio 原文:https://phpmianshi.com/?id=105有一些小伙伴私信想了解什么是nio,我们这篇详细介绍下什么...






TCP(Transmission Control Protocol) 传输控制协议

三次握手

TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接:

位码即tcp标志位,有6种标示:

SYN(synchronous建立联机) 同步报文段

ACK(acknowledgement 确认)

PSH(push传送)

FIN(finish结束) 结束报文段

RST(reset重置) 复位报文段

URG(urgent紧急) 紧急指针

Sequence number(顺序号码)

Acknowledge number(确认号码)

客户端TCP状态迁移:

CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED

服务器TCP状态迁移:

CLOSED->LISTEN->SYN收到->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED


各个状态的意义如下: 

LISTEN - 侦听来自远方TCP端口的连接请求; 

SYN-SENT -在发送连接请求后等待匹配的连接请求; 

SYN-RECEIVED - 在收到和发送一个连接请求后等待对连接请求的确认; 

ESTABLISHED- 代表一个打开的连接,数据可以传送给用户; 

FIN-WAIT-1 - 等待远程TCP的连接中断请求,或先前的连接中断请求的确认;

FIN-WAIT-2 - 从远程TCP等待连接中断请求; 

CLOSE-WAIT - 等待从本地用户发来的连接中断请求; 

CLOSING -等待远程TCP对连接中断的确认; 

LAST-ACK - 等待原来发向远程TCP的连接中断请求的确认; 

TIME-WAIT -等待足够的时间以确保远程TCP接收到连接中断请求的确认; 

CLOSED - 没有任何连接状态;


TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接,如图1所示。

(1)第一次握手:建立连接时,客户端A发送SYN包(SYN=j)到服务器B,并进入SYN_SEND状态,等待服务器B确认。

(2)第二次握手:服务器B收到SYN包,必须确认客户A的SYN(ACK=j+1),同时自己也发送一个SYN包(SYN=k),即SYN+ACK包,此时服务器B进入SYN_RECV状态。

(3)第三次握手:客户端A收到服务器B的SYN+ACK包,向服务器B发送确认包ACK(ACK=k+1),此包发送完毕,客户端A和服务器B进入ESTABLISHED状态,完成三次握手。

完成三次握手,客户端与服务器开始传送数据。

确认号:其数值等于发送方的发送序号 +1(即接收方期望接收的下一个序列号)。

图1 TCP三次握手建立连接  


TCP协议中的三次握手和四次挥手

理解:窗口和滑动窗口TCP的流量控制TCP使用窗口机制进行流量控制什么是窗口?连接建立时,各端分配一块缓冲区用来存储接收的数据,并将缓冲区的尺寸发送给另一端接收方发送的确认信息中包含了自己剩余的缓冲区...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。