同步与锁机制

       我们在学习多线程时,就不得不考虑线程安全的问题,当多线程因同时读写同一个数据而产生不可预料的后果是,就需要将各个先后才能对同一个数据的访问同步

        同步,就是指在一个线程访问一个数据还未结束的时候,其他线程不能对该数据进行访问,即将该数据的访问原子化。

        ,即为同步处理的常见方法。它是一种非强制机制,一个线程在访问数据或资源前要先获取锁,在访问结束后释放锁。如果在获取时该锁已被占用,则等待锁直到该锁被释放。

       五种同步机制的介绍:

     (1)信号量:分为二元信号量和多元信号量

        二元信号量是最简单的一种锁,它只有两种状态:占用和非占用。适合只能被一个进程独占访问的资源。当二元信号量处于非占用状态时,第一个视图获取该二元信号量的线程会获得该锁,同事将二元信号量设置为占用状态。当其他线程再次获取该锁时,将会进入等待直到锁释放。

       多元信号量则可以允许多个线程并发访问资源。一个初始值为N的信号量允许N个新城并发访问。机制如下:

        ①线程访问资源先获取信号量:

将信号量的值减一(通过sem_wait()操作)。

如果信号量的值变成负数,则进入等待状态,否则继续执行。

②访问完资源后,线程释放信号量:

将信号量的值加一(通过sem_post()操作)。

如果信号量的值小于1,则唤醒一个等待状态的线程。

(2)互斥量(互斥锁Mutex):和二元信号量很类似,资源仅同时允许一个线程访问。

信号量和互斥量的不同点:同一个信号量可以被系统中的一个线程获取之后由另一个线程释放。而互斥量则要求必须是哪个线程获取,哪个线程释放。

(3)临界区:比互斥量更加严格的同步手段。把临界区锁的获取成为进入临界区,锁的释放成为离开临界区。

临界区和互斥量与信号量的区别:一个进程创建了互斥量或信号量,另一个进程试图获取该锁是合法的。而临界区的作用范围仅限于本进程。

(4)读写锁:致力于更加特定的场合。对于读写频繁,而仅仅偶尔写入的情况,读写锁就比上述所说的三种同步机制要高效的多。对于同一个锁,读写锁有两种获取方式,共享的独占的。当锁处于空闲状态时,无论以哪种方式获取锁都能成功,并将锁置于所属的状态。如果锁处于共享状态,则其他线程以共享的方式获取锁时仍会成功,而已独占的方式获取则会进入等待。如果锁处于独占状态,其他线程不论以什么方式获取该锁,都只能进入等待状态。

(5)条件变量:作用类似于一个栅栏。对于条件变量,线程可以有两种操作,首先线程可以等待条件变量,一个条件变量可以被多个线程等待。其次,线程可以唤醒条件变量,此时等待此条件变量的线程都会被唤醒并继续支持。也就是说,使用条件变量可以是多个线程一起等待某个时间的发生,当时间发生时(条件变量被唤醒),所有线程可以一起恢复执行。

猜你喜欢

转载自blog.csdn.net/Dxiaoru/article/details/78415522