thread_guard 等价于 lock_guard / unique_lock
A thread_guard Equivalent To lock_guard / unique_lock
标准库提供了一个mutex
class,可以手动加锁和解锁:
std::mutex m;
m.lock();
// ...
m.unlock();
然而,库显然也认识到一个常见的情况就是在某个时候锁定互斥量,并在离开块时解锁它。为此,它提供 std::lock_guard
and std::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
(或一系列 thread
),并且只需要在其上调用 join
自身破坏:
std::thread t(foo);
thread_guard<std::thread> g(t);
// ...
// Join automatically
有没有类似的标准库class?
如果不是,是否有理由避免这种情况?
Scott Meyer 的书中讨论了这个问题 "Modern Effective c++"
问题是,如果有另一种默认行为(分离或连接),将导致很难发现错误,以防您忘记存在隐式操作。因此,如果未明确加入或分离,实际的默认销毁行为是断言。并且没有 "Guard" class 也是因为这个原因。
如果您总是 想加入,那么自己编写这样的 class 是安全的。但是当有人使用它并且想要分离的时候人们可以忘记析构函数会隐式地加入它。所以这就是编写这样的函数的风险。
作为替代方案,您可以使用 boost 的 scope_guard
或 folly 库(我个人更喜欢它),并在开始时明确声明您的意图,它将被执行。或者你可以写一个基于 "Guard" class 的策略,你必须在其中明确说明你想在销毁时做什么。
标准库提供了一个mutex
class,可以手动加锁和解锁:
std::mutex m;
m.lock();
// ...
m.unlock();
然而,库显然也认识到一个常见的情况就是在某个时候锁定互斥量,并在离开块时解锁它。为此,它提供 std::lock_guard
and std::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
(或一系列 thread
),并且只需要在其上调用 join
自身破坏:
std::thread t(foo);
thread_guard<std::thread> g(t);
// ...
// Join automatically
有没有类似的标准库class?
如果不是,是否有理由避免这种情况?
Scott Meyer 的书中讨论了这个问题 "Modern Effective c++"
问题是,如果有另一种默认行为(分离或连接),将导致很难发现错误,以防您忘记存在隐式操作。因此,如果未明确加入或分离,实际的默认销毁行为是断言。并且没有 "Guard" class 也是因为这个原因。
如果您总是 想加入,那么自己编写这样的 class 是安全的。但是当有人使用它并且想要分离的时候人们可以忘记析构函数会隐式地加入它。所以这就是编写这样的函数的风险。
作为替代方案,您可以使用 boost 的 scope_guard
或 folly 库(我个人更喜欢它),并在开始时明确声明您的意图,它将被执行。或者你可以写一个基于 "Guard" class 的策略,你必须在其中明确说明你想在销毁时做什么。