【问题标题】:A thread_guard Equivalent To lock_guard / unique_lock等效于 lock_guard / unique_lock 的 thread_guard
【发布时间】:2016-09-08 12:47:00
【问题描述】:

标准库提供了一个mutex 类,可以手动锁定和解锁:

std::mutex m;
m.lock();
// ...
m.unlock();

然而,库显然也认识到,一个常见的情况就是在某个时候锁定互斥体,并在离开块时解锁它。为此,它提供了std::lock_guardstd::unique_lock

std::mutex m;
std::lock_guard<std::mutex> lock(m);
// ...

// Automatic unlock

我认为线程的一种相当常见的模式是创建一个(作为堆栈变量或成员),然后join it before destructing it

std::thread t(foo);
// ...
t.join();

编写一个thread_guard 似乎很容易,它需要一个thread(或threads 的序列),并且只会调用join 自行销毁:

std::thread t(foo);
thread_guard<std::thread> g(t);
// ...
// Join automatically
  1. 有类似的标准库类吗?

  2. 如果没有,是否有理由避免这种情况?

【问题讨论】:

  • 你可以随时分离线程,它会在线程结束时自动“加入”(不是真正加入,但会发生同样的资源清理)。
  • @JoachimPileborg 谢谢。但是,分离有不同的作用,不是吗?如果你在离开块之前join(直接、间接),你就知道,一旦块退出,线程就结束了。
  • joining_thread 最近被提议但shot down
  • @T.C.很有意思!谢谢

标签: multithreading c++11 raii c++-standard-library


【解决方案1】:

Scott Meyer 的《Modern Effective c++》一书中讨论了这个问题

问题是如果有另一个默认行为(分离或连接)会导致很难找到错误,以防您忘记存在隐式操作。因此,销毁的实际默认行为是断言,如果没有明确加入或分离。也因为这个原因,没有“Guard”类。

如果您总是想加入,自己编写这样的课程是安全的。但是当有人使用它并想要分离时,人们可能会忘记析构函数会隐式加入它。所以这就是编写这样的函数的风险。

作为替代方案,您可以使用 scope_guard by boost 或 folly 库(我个人更喜欢),并在开始时明确声明您的意图,它将被执行。或者您可以编写一个基于策略的“Guard”类,您必须在其中明确说明您想在销毁时做什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-07
    • 1970-01-01
    • 2013-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-23
    相关资源
    最近更新 更多