C++ 线程互斥锁解锁顺序
考虑以下代码:C++ 线程互斥锁解锁顺序,c++,multithreading,c++11,mutex,C++,Multithreading,C++11,Mutex,考虑以下代码: #include <iostream> #include <mutex> #include <thread> #include <vector> #include <chrono> using namespace std; const int SIZE = 10; mutex myMutex; std::vector<int> strange; void add_to_vector(int i)
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
#include <chrono>
using namespace std;
const int SIZE = 10;
mutex myMutex;
std::vector<int> strange;
void add_to_vector(int i) {
lock_guard<mutex> g(myMutex);
if (strange.size() < 100) {
cout << "Dodaje do bazy" << i << std::endl;
strange.push_back(i);
cout << "Dodałem do bazy" << i << std::endl;
}
}
void f(int n) {
while (strange.size() < 100)
{
add_to_vector(n);
std::this_thread::sleep_for(std::chrono::microseconds(100));
}
}
int main()
{
thread t1(f, 1); // 0-9
thread t2(f, 2); // 10-19
thread t3(f, 3); // 20-29
thread t4(f, 4); // 30-39
thread t5(f, 5); // 40-49
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
for (auto a : strange) {
std::cout << a << ", ";
}
return 0;
}
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
常数int SIZE=10;
互斥体myMutex;
std::向量奇怪;
void add_到_向量(int i){
锁定保护g(myMutex);
if(奇怪的.size()<100){
是的,这就是线程的要点,它们可以不一定以串行顺序进行操作。你的问题是什么?根据经验法则,确保以锁定的相同顺序解锁多个互斥锁,以避免死锁。顺便说一句,是不是故意而(奇怪的.size()<100)
不在任何锁保护的范围内?标准互斥锁不保证fifo顺序,但您可以(例如)实现。尽管您可能仍然存在一个潜在问题,即某些线程在互斥锁上未被阻止,而另一个线程执行其工作并重新获取它(也就是说,在解锁和锁定互斥锁之间,或者谁先锁定互斥锁,除非你的线程也在fifo调度程序下运行)@sweet\u sugar你没有领会我的意思。size()
不是什么神奇的原子成员函数。评估奇怪的.size()
当您调用一个竞争条件时。无论您希望它们以什么顺序执行,该计算都是不受保护的,并且是竞争条件的一个配方。您最好使用while(add_to_vector(n)<100)
并让add_to_vector
锁存互斥锁,执行评估,然后返回奇怪的.size()
在闩锁的限制下拉动。