gpt4 book ai didi

c++ - 如何等待多个线程完成(使用 C++11 线程)?

转载 作者:行者123 更新时间:2023-11-28 04:51:49 26 4
gpt4 key购买 nike

我正在尝试编写一个程序,该程序使用 C++11 线程功能来生成多个线程,主线程必须等待每个生成的线程完成,并且所有生成的线程必须并行运行。我想出了以下方法:

#include <iostream>
#include <stdio.h>
#include <thread>
#include <condition_variable>
#include <mutex>

using namespace std;

class Producer
{
public:
Producer(int a_id):
m_id(a_id),
m_running(false),
m_ready(false),
m_terminate(false)
{
m_id = a_id;
m_thread = thread(&Producer::run, this);
while (!m_ready) {}
}

~Producer() {
terminate();
m_thread.join();
}

void wait() {
unique_lock<mutex> lock(m_waitForRunFinishMutex);
m_cond.wait(lock);
// avoid spurious wake up
if (m_running) {
wait();
}
lock.unlock();
cout << "wait exit " << m_id << endl;
}

void start() {
m_running = true;
m_cond.notify_all();
}

void terminate() {
start();
m_terminate = true;
}

void run() {
m_ready = true;
do {
unique_lock<mutex> lock(m_mutex);
while (!m_running) {
m_cond.wait(lock);
}

if (!m_terminate) {
cout << "running thread: " << m_id << endl;
}

m_running = false;
m_cond.notify_all();
} while (!m_terminate);
}

private:
int m_id;
bool m_running;
bool m_ready;
bool m_terminate;
thread m_thread;
mutex m_mutex;
mutex m_waitForRunFinishMutex;
condition_variable m_cond;
};

程序在只有一个线程测试时运行良好,即以下程序:

int main()
{
Producer producer1(1);
producer1.start();
producer1.wait();

return 0;
}

结果如下:

running thread: 1
wait exit: 1

但是,如果我用 2 个线程测试程序,例如:

int main()
{
Producer producer1(1);
Producer producer2(2);

producer1.start();
producer2.start();

producer1.wait();
producer2.wait();

return 0;
}

我得到以下输出:

running thread: 2
running thread: 1
wait exit 1

似乎 producer2 从未收到通知(在 producer2.wait() 中),因此程序永远不会完成。希望有人能指出我在这里遗漏了什么。

感谢大家帮助解决问题。最终问题的根本原因在已接受答案的第 (3) 点中进行了描述。我通过如下更正 wait 函数解决了这个问题:

void wait() {
unique_lock<mutex> lock(m_waitForRunFinishMutex);
while (m_running) {
m_cond.wait(lock);
}
lock.unlock();
}

最佳答案

这里是问题的快速集合,一目了然。

  1. wait() 是递归的,没有解锁它的唯一锁(根据 Detonar 的评论)

  2. while (!m_ready) {} 不在内存屏障中(尝试通过一些优化进行编译,看看会发生什么!)

  3. 如果工作线程在调用 wait() 之前完成;在等待条件变量之前不执行任何检查。由于工作线程已完成;它永远不会被唤醒。显然,在等待条件变量之前,您必须检查线程是否可以在互斥锁中被唤醒。

关于c++ - 如何等待多个线程完成(使用 C++11 线程)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48059227/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com