互斥量和信号量的区别
1.互斥量用于线程的互斥:
- 互斥:加锁解锁,是指某一资源同时只允许一个访问者对其进行访问(比如原子操作一段代码或一个变量),具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序(这个需要同步来解决),即访问是无序的,释放了锁接下来谁能竞争到谁就去访问资源。
2.信号量用于线程的同步:
- 同步:P–,V++操作,是指在互斥的基础上,通过其它机制(比如原子操作一个计数器)实现访问者对资源的有序访问。
在大多数情况下,同步已经实现了互斥(spin lock),特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源。
适用场景(顺序性角度)
互斥量值只能为0/1,信号量值可以为非负整数(当信号量初始值设置为1的时候,其实信号量就相当于互斥锁了)
-
互斥量可以用在线程间无顺序无同步要求的场景,常用在保护邻接资源的正确访问; 比如抢票,顺序随机,只要保证共享的票数正确减少即可;
-
信号量可以用在生产流水线,比如我们有ABC产品,生产完A才能生产B,生产完B才能生产C,我们就可以设置三个ABC信号量,代表他们剩余产品的个数,这样各线程之间生产的时候只需要P()--自己需要的前一个产品的信号量>=0即可生产,否则进入阻塞等待队列等V操作唤醒; 若成功生产一个之后V()++即可达到同步其他线程的目的,保证了一定顺序的同步性; 比反复加锁解锁更方便;
C++11的atomic原子操作(锁CPU访问的系统总线原理),其实和linux的mutex用法差不多,都能达到访问临界资源的线程安全,只不过效率不同,一个陷入内核上锁,一个cpu访问总线的时候加锁;
同时:
bool类型的atomic 不就是mutex嘛~
unsigned int 类型的atomic 不就是sem信号量嘛~