东莞企业网站建设预算大概多少/数据分析软件
避免多个线程同时访问共享资源,避免数据竞争,提供线程间同步。
互斥锁mutex
-
lock()上锁
-
unlock解锁
-
recursive_mutex递归锁:同一个线程可以获取多次锁,不会产生死锁。
锁管理者:
-
lock_guard锁管理者:对象构造时加锁、析构时解锁
-
scoped_lock:用于多个互斥体的免死锁RALL封装器对象构造时加锁、析构时解锁
-
unique_lock:实现可移动的互斥体所有权包装器(可以把锁解锁取下来)
条件变量
获得锁(资源)若条件不满足:条件变量wait解锁将线程放到条件变量队列中。notify唤醒后加锁放入互斥队列中。
唤醒:
-
notify_one:唤醒一个
-
notify_all:唤醒全部
等待:
-
wait:阻塞当前线程,直到条件变量被唤醒
-
wait_for:指定时长时限后
-
wait_until:指定时间点
wait分四步:
-
unlock互斥锁
-
阻塞当前线程
-
mut.lock(再次持有锁资源,唤醒线程)
-
返回
#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
using namespace std;
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void work_thread()//线程函数
{cout<<"work_thread begin"<<endl;std::unique_lock<std::mutex> lock(mtx);//mtx.lock,unique_lock不用自己释放锁资源。while(!ready)//ready==false(主线程还没改read)//防止虚假唤醒{cout<<"ready == flase"<<endl;cv.wait(lock);//没有锁(不持有资源)是不能用wait的//wait等待被唤醒}cout<<"work_thread run"<<endl;cout<<"work_thread end"<<endl;
}
int main()//主线程
{std::thread tha(work_thread);{std::unique_lock<std::mutex> lock(mtx);ready = true;cout<<"main signals ready"<<endl;}tha.join();//阻塞等待线程返回}
让三个线程分别运行A B C A B C的输出10次。
wait到条件变量队列,互斥锁释放。
条件变量队列:cv,被唤醒后放到mutex互斥队列中。
一个锁释放:互斥队列中的一个线程被唤醒到。必须获取锁才能从wait返回到就绪。
#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
using namespace std;
std::mutex mtx;
std::condition_variable cv;
const int n = 10;
int tag = 1;//1A,2B,3C,1A
void funa()
{std::unique_lock<std::mutex> lock(mtx);for (int i = 0; i < n; ++i){while (tag != 1){cv.wait(lock);}printf("funa: A \n");tag = 2;cv.notify_all();}
}
void funb()
{std::unique_lock<std::mutex> lock(mtx);for (int i = 0; i < n; ++i){while (tag != 2){cv.wait(lock);}printf("funb: B \n");tag = 3;cv.notify_all();}
}
void func()
{std::unique_lock<std::mutex> lock(mtx);for (int i = 0; i < n; ++i){while (tag != 3){cv.wait(lock);}printf("func: C \n");tag = 1;cv.notify_all();}
}
int main()
{std::thread tha(funa);std::thread thb(funb);std::thread thc(func);tha.join();thb.join();thc.join();return 0;
}