线程同步的几种方法(6种)

1. 互斥锁

  特殊的全局变量, 拥有lock和unlock两种状态, unlock互斥锁可以由某个线程获得, 当互斥锁由某个线程持有后, 这个互斥锁会锁上变成lock状态, 此后只有该线程有权利打开该锁. 其他想要获得该互斥锁的线程都会阻塞, 直到互斥锁被解锁

互斥锁类型:

  1. 普通锁

  互斥锁默认类型, 当一个线程对一个普通锁加锁以后,其余请求该锁的线程将形成一个 等待队列,并在该锁解锁后按照优先级获得它,这种锁类型保证了资源分配的公平性。一个 线程如果对一个已经加锁的普通锁再次加锁,将引发死锁;对一个已经被其他线程加锁的普 通锁解锁,或者对一个已经解锁的普通锁再次解锁,将导致不可预期的后果。

  2. 检错锁

  一个线程如果对一个已经加锁的检错锁再次加锁,则加锁操作返回EDEADLK;对一个已 经被其他线程加锁的检错锁解锁或者对一个已经解锁的检错锁再次解锁,则解锁操作返回 EPERM。

  3. 嵌套锁

  该锁允许一个线程在释放锁之前多次对它加锁而不发生死锁;其他线程要获得这个锁,则当前锁的拥有者必须执行多次解锁操作;对一个已经被其他线程加锁的嵌套锁解锁,或者对一个已经解锁的嵌套锁再次解锁,则解锁操作返回EPERM。

  4. 默认锁

  一个线程如果对一个已经加锁的默认锁再次加锁,或者虽一个已经被其他线程加锁的默 认锁解锁,或者对一个解锁的默认锁解锁,将导致不可预期的后果;这种锁实现的时候可能 被映射成上述三种锁之一。

2. 自旋锁

  自旋锁就是一个死循环, 不停的轮询, 当一个线程未获得自旋锁时, 不会像互斥锁一样进入阻塞休眠状态, 而是不停的轮询获取锁, 如果自旋锁能很快被释放, 那么性能就会很高, 如果自旋锁长时间不能够得到释放, 甚至里面还有大量的IO阻塞, 就会导致其他获取锁的线程一直空轮询, 导致CPU使用率达到100%, 特别是CPU时间

3. 信号量

  是一个计数器, 用于控制访问有限共享资源的线程数

4. 条件变量

  可以让调用线程在满足特定条件的情况下运行, 不满足条件时阻塞等待被唤醒, 必须与互斥锁搭配使用

  常用于生产者和消费者模型

5. 读写锁

  三种状态

  1. 读模式下的加锁状态

  2. 写模式下的枷锁状态

  3. 不加锁状态

一次只有一个线程可以占有写模式的读写锁,但是多个线程可以同时占有读模式的读写锁。读写锁也叫做共享-独占锁,当读写锁以读模式锁住时,它是以共享模式锁住的,当它以写模式锁住时,它是以独占模式锁住的,读读共享,读写互斥。

6. 屏障

用户协调多个进程并行工作的同步机制, 屏障允许每个线程等待, 直到所有的合作线程都达到某一点, 然后所有线程都从该点继续执行. pthread_join函数就是一种屏障, 允许一个线程等待, 直到另一个线程退出, 但是屏障对象的概念更广, 允许任意数量的线程等待,直到所有的线程完成处理工作,而线程不需要退出,当所有的线程达到屏障后可以接着工作。