进程,线程,协程的对比和选择
进程间的五种通信方式
管道
- 是半双工的,有固定的读端和写端
- 只用于亲缘关系间的通信(父子/兄弟进程)
- 只存在内存中
FIFO命名管道
类似于在进程中使用文件来传输数据,在数据读出时候同时清空数据,并且先进先出
- 可以在无关进程之间通信
- 有路径名与之关联,以一种特殊设备文件形式存在于文件系统中,但是FIFO中数据存放在内存中
消息队列
是消息链表,存放在内核中,一个消息队列有一个队列ID来标识
- 有特定格式和优先级
- 消息队列独立于进程,里面的内容不会被删除
- 可以实现随机查询,读取方式可以先进先出,也可以按类型读取
信号量
它是一个计数器,信号量用于实现进程间的互斥和同步,不是用于存储进程间的通信数据。
- 信号量用于进程同步,需要进程间传递数据要结合共享内存
- 信号量基于操作系统的PV操作(请求和释放资源),程序对信号量的操作都是原子操作
- 支持信号量组
共享内存
指两个或者多个进程共享一个给定的存储区
- 最快的进程间的通信方式,进程直接对内存进行读取
- 多进程同时操作,需要进行同步
- 信号量和共享内存常结合使用,信号量用于同步对共享内存的访问
死锁
死锁是指一组进程中进程都占有无法释放的资源,但是因为互相申请别其他进程占用的无法释放的资源而造成的死锁
死锁的四个条件
- 互斥条件:资源共享,只能一个进程使用
- 请求与保持条件:已经获得资源的进程,可以再次申请新的资源
- 非剥夺条件:已经获得资源的进程,不能强制剥夺该进程资源
- 循环等待:形成环路,每个进程都在等待对应资源的释放
死锁可能性的最根本原因:
- 是多个线程涉及到多个锁,这些锁存在着交叉,所以可能会导致了一个锁依赖的闭环;
- 默认的锁申请操作是阻塞的。
破坏死锁的方法:
- 破坏请求保持条件和非剥夺条件,获取锁设置超时时间,超时就释放,尽量避免锁不能释放的问题
- 破坏死循环等待条件,设置超时时间