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()
在闩锁的限制下拉动。