进程间通信与线程间通信


通信的目的有两种:

  • 资源互斥
  • 同步(多个进程和线程协调任务)

资源互斥

进程间资源互斥

多个进程可以访问系统中的同一个资源,但有的资源同一时间只能被一个线程使用,比如打印机。这种同一时间只能为一个线程服务的资源叫做临界资源。
一个电脑可能连接多个打印机。
举个例子:打印机相当于厕所的坑位,进程当做是要蹲坑的人。

线程间资源互斥

多个线程都可以访问同一个全局变量,但多个线程同时写全局变量时,但由于写变量并非原子操作,所以多个线程写同一个全局变量的时候,其值是未知的。我们需要线程间互斥的访问同一个全局变量,即有一个线程在写,其他的线程都需要等待。

解决资源互斥

对于进程和线程的资源互斥,都可以使用信号量的方式。(互斥量也叫互斥信号量,是信号量的特例,它只有0或者1两种状态。而信号量,可以计数)。
Windows 系统线程的资源互斥问题,还可以使用临界区。

资源互斥方法
进程间资源互斥信号量(包含互斥信号量)
线程间资源互斥信号量(包含互斥信号量),临界区(Windows系统才有)

临界区速度快于信号量,原因是临界区是非内核对象,在用户态进行操作;互斥体是内核对象,在核心态进行操作


进程(线程)同步

进程(线程)同步 倾向于多个进程(线程)发送和接收信息,协作式的完成一个任务。有人也把这个过程叫做任务编排。(指定每个线程都工作,先后顺序等等)。

线程同步

  • 对于Windows来说,使用的是Event。(Event是内核对象,可以用于线程,也可以用于进程。)
  • 对于Linux系统,使用的是条件变量。
线程同步
Event (Windows)
条件变量(Linux)

进程同步

  • 管道
    管道可以用于具有亲缘关系的进程间同步;有名管道,除了允许有亲缘关系的进程同步,还允许无亲缘关系的进程同步。

  • 信号 (Windows不支持该方式)
    信号用于通知接收进程有某种事件发生,除了用于进程间同步,还可以发给自身进程;Linux除了支持UNIX早期的信号语义函数sigal外,还支持Posix.1标准的信号函数sigaction。

  • 消息队列
    消息队列是消息的列表,包括Posix消息队列和System V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承接无格式字节流及缓冲区大小受限等缺点。

  • 共享内存
    多个进程可以访问同一块内存空间,是最快的同步方式。
    它常常和信号量结合起来使用。 在这种情况下:

    • 信号量实现资源互斥。
    • 共享内存实现进程同步。
  • 套接字
    主要用于不同机器上的进程间同步。

Go语言的线程间同步比较特别,它支持管道。而管道本来是用于进程间通信的。

Android 还有一种同步机制,叫Binder。它是用于进程间同步的。

案例

信号

Linux init进程会监视它的子进程,子进程死亡时,会给init进程发信号,通知init进程来完成资源回收。

共享内存

Android 的属性服务,它背后使用的是共享内存。

  • 只有init进程可以添加和改写属性
  • 所有的进程都拥有读权限
  • 当非init进程要添加或改写属性的时候,需要提交事件给init,init验证发送该事件进程的权限,如果权限允许,init进程便会修改或者添加属性。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李来群

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值