数据竞争
如果多个线程同时访问同一个变量, 可能对引起数据竞争:
- 如果这个访问是读操作,对这个数据没影响。
- 如果这个访问是写操作,很有可能引起数据竞争。
试想一下,如果线程A想要对主线程中的变量num进行加一操作,刚读取变量A的值后,时间片用完,转入阻塞状态,此时线程B主线程中的变量num进行加一操作。此后线程A再次执行,但还是用之前读取的num值进行操作,而没有感知到线程B已经对num变量进行过修改。
互斥对象
mutex对象是指定代码的访问。
头文件
#include<mutex>
code
分别用两个线程t1,t2对同一个变量进行加10000的操作。如果不加互斥变量进行加锁操作,最后a的值是14452。加锁之后,值才是20000。
#include<iostream>
#include<thread>
#include<mutex>
static int a = 0;
std::mutex mu;
void Add1000() {
for (int i=0; i<10000; i++) {
mu.lock();
a++;
mu.unlock();
}
}
int main() {
std::thread t1(Add1000);
std::thread t2(Add1000);
t1.join();
t2.join();
std::cout << "after t1 and t2, a is " << a << std::endl;
return 0;
}
上述代码中加锁操作是用户调用lock和unlock完成的,但这其中存在一个风险就是如果临界区代码出现意外,提前退出,这样unlock操作就不能执行。从而导致其他线程不能再访问这段临界区代码了。因此更健壮的使用lock_guard,无论临界区代码是否异常,都会执行unlock操作。
std::mutex mu;
// method1
mu.lock();
// Critical section code
mu.unlock();
//method2:
std::lock_guard<std::mutex> locker(mu);
// critical section code

本文探讨了在C++多线程环境中可能出现的数据竞争问题,当多个线程同时访问并修改同一变量时,可能会导致数据不一致。通过引入互斥对象如mutex,可以确保对共享资源的访问得到控制,防止数据竞争。示例代码展示了如何使用mutex进行加锁和解锁操作,以及更安全的lock_guard机制,以保证即使在临界区代码异常情况下也能正确解锁。

305

被折叠的 条评论
为什么被折叠?



