线程之间的锁有:互斥锁、条件锁、自旋锁、读写锁、递归锁。一般而言,锁的功能越强大,性能就会越低。
互斥锁用于控制多个线程对他们之间共享资源互斥访问的一个信号量。也就是说是为了避免多个线程在某一时刻同时操作一个共享资源。例如线程池中的有多个空闲线程和一个任务队列。任何是一个线程都要使用互斥锁互斥访问任务队列,以避免多个线程同时访问任务队列以发生错乱。
在某一时刻,只有一个线程可以获取互斥锁,在释放互斥锁之前其他线程都不能获取该互斥锁。如果其他线程想要获取这个互斥锁,那么这个线程只能以阻塞方式进行等待。
使用 :std::mutex
条件锁就是所谓的条件变量,某一个线程因为某个条件为满足时可以使用条件变量使改程序处于阻塞状态。一旦条件满足以“信号量”的方式唤醒一个因为该条件而被阻塞的线程。最为常见就是在线程池中,起初没有任务时任务队列为空,此时线程池中的线程因为“任务队列为空”这个条件处于阻塞状态。一旦有任务进来,就会以信号量的方式唤醒一个线程来处理这个任务。
使用 :pthread_cond_t
个线程想要获取一个被使用的自旋锁,那么它会一致占用CPU请求这个自旋锁使得CPU不能去做其他的事情,直到获取这个锁为止,这就是“自旋”的含义。
使用 :spinlock_t
写者:写者使用写锁,如果当前没有读者,也没有其他写者,写者立即获得写锁;
否则写者将等待,直到没有读者和写者。
读者:读者使用读锁,如果当前没有写者,读者立即获得读锁;否则读者等待,直到没有写者。
操作 | 函数说明 |
---|---|
初始化读写锁 | pthread_rwlock_init 语法 |
读取读写锁中的锁 | pthread_rwlock_rdlock 语法 |
读取非阻塞读写锁中的锁 | pthread_rwlock_tryrdlock 语法 |
写入读写锁中的锁 | pthread_rwlock_wrlock 语法 |
写入非阻塞读写锁中的锁 | pthread_rwlock_trywrlock 语法 |
解除锁定读写锁 | pthread_rwlock_unlock 语法 |
销毁读写锁 | pthread_rwlock_destroy 语法 |
所谓递归锁,就是在同一线程上该锁是可重入的,对于不同线程则相当于普通的互斥锁。
使用规则:例如函数a需要获取锁mutex,函数b也需要获取锁mutex,同时函数a中还会调用函数b。如果使用std::mutex必然会造成死锁。但是使用std::recursive_mutex就可以解决这个问题。
使用 :std::recursive_mutex
死锁至少有两个互斥量mutex1,mutex2。
以上给出了导致死锁的四个必要条件,只要系统发生死锁则以上四个条件至少有一个成立。事实上循环等待的成立蕴含了前三个条件的成立,似乎没有必要列出然而考虑这些条件对死锁的预防是有利的,因为可以通过破坏四个条件中的任何一个来预防死锁的发生。
常规做法:
保证多个互斥量上锁的顺序一样就不会造成死锁。
std::lock()函数模板:
std::lock_guard的std::adopt_lock参数
原文:https://www.cnblogs.com/lihaihui1991/p/14281117.html