线程同步的方法有哪些?

一、线程同步和线程互斥

首先我们要清楚什么是线程同步和线程互斥:
1、线程同步:线程同步指的是多个线程之间协调同步,按照预定的先后次序进行运行,这种先后次序取决于要完成的特定任务,最基本的场景就是:A线程要完成的任务依赖于B线程的数据。

2、线程互斥:线程互斥是指对于线程共享的线程资源,在各个线程访问时具有排它性。当有若干个线程要访问同一共享资源时,任何时刻只允许一个线程进行访问,直到占有资源者放弃使用该资源。线程互斥可以看成一种特殊的线程同步

二、线程同步的方式

1、互斥锁

      当有多个线程需要访问同一个资源时,如果不做处理,有时候就会出现问题,比如有两个线程需要使用打印机,进程A正在使用,而进程B也要使用打印机,此时打印出来的东西就是错乱的。互斥锁就是控制对共享资源的使用。互斥锁只有两种状态:加锁、解锁。

互斥锁的特点:

  • 原子性:把互斥量锁定位一个原子操作,这就保证了如果同一时间只会有一个线程锁定共享资源
  • 唯一性:如果一个线程锁定了某个互斥量,那么只有该线程可以使用这个被锁定的互斥量
  • 非繁忙等待:如果一个线程锁定了某互斥量,另一个线程又来访问该互斥量,则第二个线程会被挂起,当第一个线程解锁该互斥量后唤醒第二个线程对该互斥量进行访问。

2、条件变量:

       与互斥锁不同,条件变量是用来等待而不是用来上锁的。条件变量用来锁定一个线程,直到某个特殊的条件发生为止。通常条件变量和互斥锁同时发生。

条件变量可以是我们睡眠等待某种情况的发生。条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:

  1. 一个线程等待“条件变量的条件成立”而挂起
  2. 另一个线程使条件成立

      条件的检测是在互斥锁的保护下进行的。线程在改变条件变量的状态之前必须先锁定互斥量。如果一个条件为假,则线程自动阻塞,并释放等待状态改变的互斥锁。如果另外一个线程改变了条件,它发信号给相关联的条件变量,唤醒一个或多个等待它的线程,重新获得互斥锁,重新评价条件。

条件变量的操作流程如下:

  • 初始化条件变量
  • 等待条件成立
  • 激活条件变量
  • 清除条件变量

3、信号量

      使用信号量首先我们要清楚临界资源和临界区的概念,临界资源就是同一时刻只允许一个线程(或进程)访问的资源,临界区就是访问临界资源的代码段。

      信号量是一种特殊的变量,用来控制对临界资源的使用,在多个进程或线程都要访问临界资源的时候,就需要控制多个进行或线程对临界资源的使用。信号量机制通过p、v操作实现。p操作:原子减1,申请资源,当信号量为0时,p操作阻塞;v操作:原子加1,释放资源。

信号量的使用及实例:信号量

4、读写锁

      读写锁和互斥锁类似,不过读写锁允许更改的并行性。互斥锁要么是加锁状态,要么是不加锁状态。而读写锁可以有三种状态:读模式下的加锁、写模式下的加锁、不加锁 状态。一次只有一个线程可以占有写模式下的读写锁,但是可以有多个线程占有读模式下的读写锁。

读写锁的特点:

  • 如果有线程读数据,则允许其他线程读数据,但不允许写
  • 如果有线程写数据,则不允许其他线程进行读和写

5、自旋锁

      自旋锁和互斥锁的功能一样,但是互斥锁在线程阻塞时会让出cpu,而自旋锁则不会让出cpu,一直等待,直到得到锁。


 

猜你喜欢

转载自blog.csdn.net/qq_41727218/article/details/87943748