gpt4 book ai didi

c++ - 终止 worker

转载 作者:行者123 更新时间:2023-11-28 07:44:02 26 4
gpt4 key购买 nike

我有一个启动多个工作线程的函数。每个工作线程都由一个对象封装,该对象的析构函数将尝试加入线程,即调用if (thrd_.joinable()) thrd_.join();。但是,每个 worker 必须完成多少工作是先验未知的。管理功能使用互斥锁和条件变量将工作单元分配给线程。如果没有更多的工作要做,则在持有互斥量的同时设置某个标志,然后通知所有阻塞在条件变量上的线程,以便它们醒来,注意到更改的标志,然后关闭。

即使主线程中出现异常,我也希望此关闭工作。在 Java 中,我会使用 finally 子句来始终设置标志并在工作处理循环结束时通知线程。作为C++ doesn't have finally ,我写了自己的替换:

class FinallyGuard {
private:
std::function<void()> f_;
public:
FinallyGuard(std::function<void()> f) : f_(f) { }
~FinallyGuard() { f_(); }
};

void Manager::manageWork(unsigned NumWorkers) {
// Order matters: destructors are called in reverse order and will
// 1. release the mutex lock so that workers can proceed
// 2. unblock all threads using the finally workalike
// 3. destroy the workers and join their threads
std::forward_list<Worker> workers;
FinallyGuard signalEndGuard([this] {
std::unique_lock<std::mutex> lk(mtx_);
done_ = true;
beginWork_.notify_all();
});
std::unique_lock<std::mutex> lk(mtx_);
for (unsigned i = 0; i != numWorkers; ++i)
workers.emplace_front(this);
while (haveMoreWork()) {
// …
}
}

但我显然是在考虑其他语言的概念。 有没有更像 C++ 的方法来实现这一点?解决方案要么需要执行一些代码,既可以从方法正常返回,也可以在抛出异常的情况下执行,或者提供一些更好的机制唤醒工作人员而不是标志和条件变量组合。

最佳答案

C++ 中确实存在 try finally 等价物,尽管核心语言中没有。它被称为 ScopeGuard,最初由 Andrej Alexandrescu 创建,他是 C++ 领域的“摇滚明星”之一。他在 2012 年 C++ 和 Beyond session 上展示了新版本 http://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu-Systematic-Error-Handling-in-C

更重要的是这里的代码: https://gist.github.com/KindDragon/4650442

您的示例做的事情几乎相同。如果您希望其他 C++ 程序员理解您的意思,您可能应该将其称为 ScopeGuard 或使用 Alexandrescus 代码(您可能应该将其放入库或公共(public)包含中,它经常被使用)。 C++ 程序员对所有事情都使用 RAII,在我看来,表达意图很重要,

SCOPE_EXIT {
std::unique_lock<std::mutex> lk(mtx_);
done_ = true;
beginWork_.notify_all();
};

在你的情况下。

我工作的地方 ScopeGuard 被认为是很好的风格,并且很好地通过了代码审查。如果您想将其用于商业用途,它也是公共(public)领域。

关于c++ - 终止 worker ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15222502/

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