互斥
在线程中出现资源竞争是和正常的,如 :
void run(){
while (1){
cout << "aa" << endl;
sleep(1);
}
}
void run2(){
while (1){
cout << "bb" << endl;
sleep(1);
}
}
int main() {
thread t(run);
thread t2(run2);
t2.join();
t.join();
return 0;
}
会出现这种情况, 两个输出内容打印在了一起。
因为在c++中cout 函数是不能被复制的,只有一份, 所有,出现了 t t2 线程抢夺 cout 资源,在 t 线程没有完成 使用 cout 输出时 cout 被 t2 线程抢到了,所以就出现了 两个输出内容连在一起的情况
如何避免该情况呢, 可以使用上锁功能,
在发生资源竞争的时候上锁,等到使用完后解锁
mutex m;
void run(){
while (1){
m.lock();
cout << "aa" << endl;
m.unlock();
sleep(1);
}
}
void run2(){
while (1){
m.lock();
cout << "bb" << endl;
m.unlock();
sleep(1);
}
}
int main() {
thread t(run);
thread t2(run2);
t2.join();
t.join();
return 0;
}
这样就可以防止cout 出现竞争问题
lock_guard
使用锁的时候需要我们知道要在哪里解锁,对程序员有条件要求, 可以使用 lock_guard
lock_guard 对 mutex 进行了包装,在lock_guard 上锁后 当这个程序结束或者上锁是在循环中的当再次循环的时候 lock_guard 对象会调用 析构函数,对上锁的资源进行解锁释放资源
mutex m;
void run(){
while (1){
//执行这句话,即上锁,等本次循环结束,会自动释放锁
lock_guard<mutex> lg(m);
cout << "aa" << endl;
sleep(1);
}
}
void run2(){
while (1){
//执行这句话,即上锁,等本次循环结束,会自动释放锁
lock_guard<mutex> lg(m);
cout << "bb" << endl;
sleep(1);
}
}
int main() {
thread t(run);
thread t2(run2);
t2.join();
t.join();
return 0;
}
这样就不用考虑在哪里解锁了
unique_guard
unique_guard 拥有 lock_guard 的所以功能,还可以手动解锁,比 lock_guard 灵活
mutex m;
void run(){
while (1){
//执行这句话,即上锁,等本次循环结束,会自动释放锁
unique_lock<mutex> ul(m);
cout << "aa" << endl;
// 也可以提前手动解锁
ul.unlock();
sleep(1);
}
}
void run2(){
while (1){
//执行这句话,即上锁,等本次循环结束,会自动释放锁
unique_lock<mutex> ul(m);
cout << "bb" << endl;
// 也可以提前手动解锁
ul.unlock();
sleep(1);
}
}
int main() {
thread t(run);
thread t2(run2);
t2.join();
t.join();
return 0;
}