如何在 C++ 中正确使用循环中的互斥锁?

How to use mutex in loops properly in c++?

我是线程和互斥体的新手,我正在努力学习它们。我写了一些代码,通常创建一个队列,将文件中的所有数字排入队列(这个文件有将近 20.000 行和大量信息),因为这个文件包含大量信息,因为我需要有多线程,在开始用户创建线程数,然后我停留在 while 循环中的部分我想查看哪些线程进入循环以从队列中取出 id,但显然只有第一个创建的线程进入并使所有线程出队,我使用互斥锁确保当一个线程进入循环时让它进行处理(出列一个数字)然后解锁这个互斥量以便其他线程可以进入但显然我犯了一个错误。这是代码`

void printer( DynIntQueue  & myQueue) // takes the Dynamic Queue 
{
    //int count = 0;
    queMutex.lock(); // lock it before any threads come it 
    while(!myQueue.isEmpty()) // check this condition
    {
        int num;
        
        cout << "Thread " << this_thread::get_id << " is working" << endl; // this is for printing out which threads enter this loop
        myQueue.dequeue(num); // deqeueu this number from queue
        
        queMutex.unlock(); // unlock this in order to next thread might enter
        queMutex.lock();   // when this thread enters lock it in order to other threads to wait
        
        
    }
    queMutex.unlock(); // if myQueue is empty since it is firsly locked, unlock this 
    
    
}`

我的输出是这样的: Thread 005C1659 is working Thread 005C1659 is working Thread 005C1659 is working Thread 005C1659 is working Thread 005C1659 is working Thread 005C1659 is working Thread 005C1659 is working Thread 005C1659 is working Thread 005C1659 is working Thread 005C1659 is working 这一直持续到 myQueue 为空且具有相同的线程。我如何确保其他线程可能进入此循环?

已编辑:这是主要部分`

int main()
{
    DynIntQueue firstQueue;
    
    ifstream input;
    string line;
    int numofthreads;

    input.open("data.tsv");
    getline(input, line); // for first empty
    int id, houseAge, avgRooms, avgBedRooms, latitue, longitute, medianPrice;

    cout << "Please enter the number of threads you want " << endl;
    cin >> numofthreads;
    
    vector <thread> Threads(numofthreads);

    while (!input.eof())
    {
        getline(input, line);
        istringstream divider(line);
        divider >> id >> houseAge >> avgRooms >> avgBedRooms >> latitue >> longitute >> medianPrice;
        firstQueue.enqueue(id);
    }

    for (int i = 0; i < numofthreads; i++)
    {
        Threads[i] = thread(&printer, ref(firstQueue));

    }   
    
     for (int i = 0; i < numofthreads; i++)
     {
         Threads[i].join();
     }
     
     return 0;
}

注意:std::this_thread::get_id() 是一个函数,因此您应该调用它。我认为这只是一个 copy/paste 错误。

如果我在打开和关闭队列之间添加一些工作,我会清楚地看到有两个线程在使用队列。

我认为您对显示的代码没有任何问题。

#include <iostream>
#include <thread>
#include <mutex>
#include <queue>


struct DynIntQueue {
  bool isEmpty() const { return q_.empty(); }
  void dequeue(int &elem) { elem = q_.front(); q_.pop(); }
  std::queue<int> q_{{10, 20, 4, 8, 92}};
};

std::mutex queMutex;

void printer( DynIntQueue  & myQueue) {
    queMutex.lock();
    while(!myQueue.isEmpty()) {
      int num;
      std::cout << "Thread " << std::this_thread::get_id() << " is working" << std::endl;
      myQueue.dequeue(num);
      queMutex.unlock();
      std::cout << "working outside the lock" << std::endl;
      std::cout << "working outside the lock" << std::endl;
      std::cout << "working outside the lock" << std::endl;
      std::cout << "working outside the lock" << std::endl;
      std::cout << "working outside the lock" << std::endl;
      queMutex.lock();
    }
    queMutex.unlock();   
}

int main() {
  std::cout << "Hello World!\n";
  DynIntQueue q;

  std::thread t1([&q]() { printer(q); });
  std::thread t2([&q]() { printer(q); });
  t1.join();
  t2.join();
}
$ clang++-7 -pthread -std=c++17 -o main main.c
$ ./main
Hello World!
Thread 139686844172032 is working
working outside the lock
working outside the lock
working outside the lock
working outside the lock
working outside the lock
Thread 139686835779328 is working
working outside the lock
working outside the lock
working outside the lock
working outside the lock
working outside the lock
Thread 139686844172032 is working
working outside the lock
working outside the lock
working outside the lock
working outside the lock
working outside the lock
Thread 139686835779328 is working
working outside the lock
working outside the lock
working outside the lock
working outside the lock
working outside the lock
Thread 139686844172032 is working
working outside the lock
working outside the lock
working outside the lock
working outside the lock
working outside the lock