如何用C++ std::thread同步这种特殊情况的线程

yvfmudvl  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(69)

下面的例子我需要一些帮助:我有一个主程序,它将同一个函数的多个示例作为线程启动。被调用的函数至少分为两部分。首先,每个示例都必须完成函数的Part 1,然后才能继续执行Part 2。这里我需要同步它们。为了更容易理解,我将编写一些示例代码:

void TMainForm::foo(int numThreads)
{
    std::cout << "Part 1: do some work" << std::endl;

    /* HERE NEEDS TO BE SOMETHING THAT CHECKS WHETHER EVERY INSTANCE HAS DONE PART 1 !!*/

    std::cout << "Part 2: do some work" << std::endl;
}
//---------------------------------------------------------------------------

void TMainForm::StartingThreads()
{
    int threads = std::thread::hardware_concurrency();
    std::vector<std::thread> t(threads);

    for (int i = 0; i < threads; i++)
        t[i] = std::thread(foo, threads);

    for (int i = 0; i < threads; i++)
        t[i].join();
}
//---------------------------------------------------------------------------

字符串
我尝试使用互斥锁,但它对我不起作用。我递增一个原子变量(比如说atomic a),如果值小于numThreads,我就执行mutex::lock。当最后一个示例完成它的工作时,它会执行mutex::unlock。但我的线程总是在Part 1之后卡住。
有人知道吗?

mec1mxoz

mec1mxoz1#

如果你用的是C++ 20,那么其他人已经给了你一个答案,如果你17岁或以上,那么我会做一个类,你可以疯狂地进行单元测试。

class Barrier {
public:
    Barrier(int dc = 1): desiredCount(dc) {}

    void done() {
        std::unique_lock<std::mutex> lock(mutex);
        ++doneCount;
        condVar.notify_all();
    }

    void waitReady() {
        std::unique_lock<std::mutex> lock(mutex);
        while (doneCount < desiredCount) {
            condVar.wait(lock);           
        }
    }

private:
    std::mutex mutex;
    std::cond_var condVar;
    int desiredCount = 1;
    int doneCount = 0;
};

字符串
然后在你的代码中,将其中一个初始化为线程数,然后在线程中:

barrier.done();
barrier.waitReady();


我在适当的地方写这个--可能不是完美的代码。还有其他的方法来使用wait(你可以传递一个 predicate ),但这是我一直使用的模式。

相关问题