0%

进程间通信

原子操作,即不可分割开的操作;该操作一定是在同一个cpu时间片中完成,这样即使线程被切换,多个线程也不会看到同一块内存中不完整的数据。

线程同步的主要方式–线程锁 线程同步最常用的方法是使用(Lock)。锁是一种非强制机制,每一个线程访问数据或资源之前,首先试图获取(Acquireuytreewq)锁,并在访问结束之后释放(release)。在锁已经被占用时获取锁,线程会等待,直到该锁被释放。

互斥锁 是在很多平台上都比较常用的一种锁。它属于sleep-waiting类型的锁。即当锁处于占用状态时,其他线程会挂起,当锁被释放时,所有等待的线程都将被唤醒,再次对锁进行竞争。在挂起与释放过程中,涉及用户态与内核态之间的context切换,而这种切换是比较消耗性能的。

自旋锁 与互斥锁有点类似,只是自旋锁被某线程占用时,其他线程不会进入睡眠(挂起)状态,而是一直运行(自旋/空转)直到锁被释放。由于不涉及用户态与内核态之间的切换,它的效率远远高于互斥锁。

**信号量(Semaphore)**,有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。

信号量可以分为几类:

  • 二进制信号量(binary semaphore) / 二元信号量 :只允许信号量取0或1值,,只有两种状态:占用与非占用,其同时只能被一个线程获取。
  • 整型信号量(integer semaphore):信号量取值是整数,它可以被多个线程同时获得,直到信号量的值变为0。
  • 记录型信号量(record semaphore):每个信号量s除一个整数值value(计数)外,还有一个等待队列List,其中是阻塞在该信号量的各个线程的标识。当信号量被释放一个,值被加一后,系统自动从等待队列中唤醒一个等待中的线程,让其获得信号量,同时信号量再减一。

信号量通过一个计数器控制对共享资源的访问,信号量的值是一个非负整数,所有通过它的线程都会将该整数减一。如果计数器大于0,则访问被允许,计数器减1;如果为0,则访问被禁止,所有试图通过它的线程都将处于等待状态。

条件变量 (Condition Variable) 作为一种同步手段类似于栅栏,允许线程以一种无竞争的方式等待某个条件的发生。当该条件没有发生时,线程会一直处于休眠状态。当被其它线程通知条件已经发生时,线程才会被唤醒从而继续向下执行。条件变量是比较底层的同步原语,直接使用的情况不多,往往用于实现高层之间的线程同步。使用条件变量的一个经典的例子就是线程池(Thread Pool)了。

未完待续~

共享内存

共享内存允许两个或者多个进程共享一个给定的存储区,因为数据不需要再客户即和服务器之间复制,所以共享内存是最快的一种 I IPC。使用共享内存唯一的诀窍就是多个进程之间对一给定的存储区之间数据的同步存取问题。通常,信号量被用来实现对共享存储存取的同步。(记录锁也可以用于这种场合)。

对于操作系统而言,在并行程序设计中难免会遇到数据同步和共享的问题,本文针对这个问题,以windows系统为例回顾一下资源同步的相关问题。

要点如下:

1.同步和数据共享数据征用

2.同步原语 1.互斥和临界区 2.自旋锁 3.信号量 4.读写锁 5.屏障 6.原子操作与无锁代码

reference

[1] https://juejin.cn/post/6844903543527178248

小主,路过打个赏再走呗~