ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

多线程vs多进程

2021-07-25 12:04:03  阅读:169  来源: 互联网

标签:同步 信号量 互斥 vs 线程 进程 多线程 CPU


多线程/多进程应用场景

当我们的程序中存在重复性较高的工作,我们通常希望多个“单位”同时操作以提高该工作的效率。这个“单位”为进程or线程,那么什么场景下选择进程,什么场景下选择线程呢?

进程和线程,本质上的区别是CPU时间调度上的时间片。

多线程由于不需要进行进程间的上下文切换能够提高进程时间片内CPU的利用效率,但是不会因此占用更多的CPU资源(处理时间片)。

相反,如果同时运行多个进程,每个进程独自占用CPU的资源,尤其对于性能较佳的多核CPU而言,能够大幅提升运行速度(占用更多的时间片资源)。

 

大部分任务都是IO密集型任务,CPU消耗很少,花费更多时间等待IO操作完成,对于这类任务,瓶颈不在CPU而在IO,没有必要采用多进程占用更多的CPU资源,可以使用多线程。

对于CPU密集型任务,大多数时间都是CPU在运行计算,可以考虑采用多进程占用更多的CPU资源,但需要考虑同时运行的任务数量与CPU核心数相匹配。

 

线程间同步

线程共享同一资源,虽然线程被CPU作为最小执行单元,但是很少有线程能够在自己的时间片内执行完。当多个线程请求修改同一变量,会导致变量的处理结果不可控。

为了确保同一变量的按序修改,在某一线程修改变量时禁止其他线程对其的任何访问的行为称作线程同步

1.互斥锁

本质就是一个特殊的全局变量,拥有lock和unlock两种状态,unlock的互斥锁可以由某个线程获得,一旦获得,这个互斥锁会锁上变成lock状态,此后只有该线程由权力打开该锁,其他线程想要获得互斥锁,必须得到互斥锁再次被打开之后。

 

互斥锁的弊端:被访问的变量代表一个状态,而某个线程需要反复询问该状态是否改变时,会造成线程反复请求变量的权限,反复加锁和解锁,耗费大量资源,效率低。

 

其实上述情况,请求状态变量的线程只需要在状态改变的时候被唤醒就可以了。另一种同步方式条件变量能够实现这一操作。

 

2.条件变量

条件变量和互斥锁往往配合使用,例:

(1)线程A获得互斥锁pthread_mutex_lock(&qlock);

(2)线程A等待条件pthread_cond_wait(&qready,&qlock)à该步骤会自动释放(1)中互斥锁;

(3)线程B获得互斥锁pthread_mutex_lock(&qlock);并改变相关变量;

(4)线程B激活条件变量pthread_cond_signal(&qready);

(5)线程B解锁;

(6)线程A自动获得原互斥锁(pthread_cond_wait(&qready,&qlock)干的),并继续运行。

 

上述两种线程同步方式能够解决在变量存在修改行为时的访问互斥与同步,但是如果变量不需要修改能不能让多个读线程同时访问呢?

 

3.读写锁

读写锁=共享-独占锁

锁处于读模式时可以线程共享,而锁处于写模式时只能独占。

读写锁有两种策略:强读同步和强写同步。

在强读同步中,总是给读者更高的优先权,只要写者没有进行写操作,读者就可以获得访问权限。à读写锁默认的模式,静态初始化只能默认

在强写同步中,总是给写者更高的优先权,读者只能等到所有正在等待或者执行的写者完成后才能进行读。

 

上面三种同步方式都是针对某一资源的写互斥,那么如果同时管理多个可访问资源呢?

 

4.信号量

信号量对访问资源的线程计数,当线程请求资源访问时,信号量>0则授予线程访问权限,并将信号量-1,若信号量=0,则认为资源并发量已满,组织线程访问。

例:10个顾客,2个服务窗口;5辆车,3个车位。

 

进程间通信

管道只能承载无格式字节流,缓冲区大小受限。

1.管道

管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系(共有祖先)的进程间使用。fifo

2.有名管道

有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。mkfifo

3.信号

信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。(参考线程间同步)

4.信号量

(1)信号量用于进程间同步,若要在进程间传递数据需要结合共享内存。(参考线程间同步)

(2)信号量基于操作系统的 PV 操作,程序对信号量的操作都是原子操作。

(3)每次对信号量的 PV 操作不仅限于对信号量值加 1 或减 1,而且可以加减任意正整数。

     (4)支持信号量组。

5.消息队列

消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。

(1)消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级。

(2)消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除。

(3)消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。

6.共享内存

共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。

(1)共享内存是最快的一种 IPC,因为进程是直接对内存进行存取。

(2)因为多个进程可以同时操作,所以需要进行同步。

(3)信号量+共享内存通常结合在一起使用,信号量用来同步对共享内存的访问。

7.套接字

  IP+Port,用于不同设备的进程间通信。socket

标签:同步,信号量,互斥,vs,线程,进程,多线程,CPU
来源: https://www.cnblogs.com/filletnotfish/p/15057392.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有