- 多线程
- 互斥量
- 自旋锁
- (条件锁)条件变量
- 同步队列
多线程 互斥量
互斥量也称为互斥锁,是一种访问临界区资源的特殊变量。当一个线程对一个共享资源加上互斥锁时,另一个线程想要获取这把互斥锁时,该线程会阻塞挂起,加入线程等待队列,让出CPU时间,CPU可以执行别的任务,直到持有这把互斥锁的线程释放锁,内核才切换到该线程进行获得互斥锁。
故互斥锁有个缺点:就是需要进行两次的线程上下文切换。
使用场景:线程持有锁的时间较长,也就是释放锁较慢的场景(线程处理任务较慢情况)适合使用。
自旋锁自旋锁:当一个线程访问资源时加上自旋锁后,当其他线程想获取这把自旋锁,则不会使得线程阻塞挂起的状态,也不会让出CPU,而占有CPU时间,不断循环判断这把自旋锁是否可用。
缺点:会一直占有CPU,直到获得的自旋锁可用,如果当持有自旋锁的线程执行任务时间较长,那么处于等待的线程将一直占有CPU,若等待的线程过多,那么整个系统的性能将很低效。
使用场景:线程持有自旋锁后,执行的任务时间较短,适合使用自旋锁,减少了线程的上下文切换。
比如智能指针的引用计数机制使用的是自旋锁。
条件锁:以未满足某种条件而锁定的条件变量。当线程加上锁后,当条件未满足时,则会释放掉锁,阻塞等待条件满足;当条件满足后,其他线程会发起通知,使得唤醒被阻塞的线程,之后加上锁进行操作。
同步队列#include#include #include #include #include #include using namespace std; class Synqueue { public: Synqueue(int _size = 3) : size(_size){ } ~Synqueue() { } public: bool isFull() { return que.size() == size; } bool isEmpty() { return que.empty(); } void syn_push(const int& value) { unique_lock lk(m_mutex); while (isFull()) { cout << "queue is full" << endl; m_notfull_cond.wait(lk); cout << "queue is not full" << endl; } que.push(value); cout << "push value = " << value << endl; //lk.unlock(); m_notempty_cond.notify_one(); } int syn_pop() { unique_lock lk(m_mutex); while (isEmpty()) { cout << "queue is empty" << endl; m_notempty_cond.wait(lk); cout << "queue is not empty" << endl; } int value = que.front(); que.pop(); cout << "pop value = " << value << endl; //lk.unlock(); m_notfull_cond.notify_one(); return value; } private: int size; queue que; mutex m_mutex; condition_variable m_notfull_cond; condition_variable m_notempty_cond; }; int main() { Synqueue syn; thread t0([&] { syn.syn_pop();}); thread t1([&] { syn.syn_push(10);}); thread t2([&] { syn.syn_push(20);}); thread t3([&] { syn.syn_push(30);}); thread t4([&] { syn.syn_push(40);}); thread t5([&] { syn.syn_push(50);}); thread t6([&] { syn.syn_pop();}); //thread t7([&] { syn.syn_pop();}); t0.join(); t1.join(); t2.join(); t3.join(); t4.join(); t5.join(); t6.join(); //t7.join(); return 0; }



