-
读写锁特点:
-
读写锁有三种状态:读加锁状态、写加锁状态和不加锁状态
-
只有一个线程可以占有写状态的锁,但可以有多个线程同时占有读状态锁,这也是它可以实现高并发的原因。当其处于写状态锁下,任何想要尝试获得锁的线程都会被阻塞,直到写状态锁被释放;如果是处于读状态锁下,允许其它线程获得它的读状态锁,但是不允许获得它的写状态锁,直到所有线程的读状态锁被释放;为了避免想要尝试写操作的线程一直得不到写状态锁,当处于读模式的读写锁接收到一个试图对其进行写模式加锁操作时,便会阻塞后面对其进行读模式加锁操作的线程。 即当读写锁感知到有线程想要获得写状态锁时,便会阻塞其后所有想要获得读状态锁的线程。这样当读模式的锁解锁后,要获得写状态锁的线程能够访问此锁保护的资源。所以读写锁非常适合资源的读操作远多于写操作的情况。
-
1)多个读者可以同时进行读
-
2)写者必须互斥(只允许一个写者写,也不能读者写者同时进行)
-
3)写者优先于读者(一旦有写者,则后续读者必须等待,唤醒时优先考虑写者)
-
-
互斥锁特点:
-
在访问共享资源之前对进行加锁操作,在访问完成之后进行解锁操作。 加锁后,任何其他试图再次加锁的线程会被阻塞,直到当前线程解锁。 如果解锁时有一个以上的线程阻塞,那么所有该锁上的线程都被编程就绪状态, 第一个变为就绪状态的线程又执行加锁操作,那么其他的线程又会进入等待。 在这种方式下,只有一个线程能够访问被互斥锁保护的资源。
-
一次只能一个线程拥有互斥锁,其他线程只有等待
-
-
自旋锁特点:
-
自旋锁是一种特殊的互斥锁,当资源被枷锁后,其他线程想要再次加锁,此时该线程不会被阻塞睡眠而是陷入循环等待状态(CPU不能做其它事情),循环检查资源持有者是否已经释放了资源,这样做的好处是减少了线程从睡眠到唤醒的资源消耗,但会一直占用CPU的资源。适用于资源的锁被持有的时间短,而又不希望在线程的唤醒上花费太多资源的情况。
-
-
从 实现原理上来讲,互斥锁属于sleep-waiting(睡眠等待)类型的锁。例如在一个双核的机器上有两个线程(线程A和线程B),它们分别运行在Core0和 Core1上。假设线程A想要通过pthread_mutex_lock操作去得到一个临界区的锁,而此时这个锁正被线程B所持有,那么线程A就会被阻塞 (blocking),Core0 会在此时进行上下文切换(Context Switch)将线程A置于等待队列中,此时Core0就可以运行其他的任务(例如另一个线程C)而不必进行忙等待。而自旋锁则不然,它属于busy-waiting(忙等待)类型的锁,如果线程A是使用pthread_spin_lock操作去请求锁,那么线程A就会一直在 Core0上进行忙等待并不停的进行锁请求,直到得到这个锁为止。
-