Tom*_*Tom 7 c++ multithreading c++11 stdatomic
我有一个简单的布尔值,我需要以线程安全的方式进行测试和设置.如果一个线程已经在工作,我希望第二个线程退出.如果我理解std::atomic_flag正确,这应该工作正常.但是,我不自信我理解std::atomic_flag正确:)我似乎无法在网上找到很多简单的例子,除了这个螺旋锁示例:
// myclass.cpp
#using <atomic>
namespace // anonymous namespace
{
std::atomic_flag _my_flag = ATOMIC_FLAG_INIT;
} // ns
myclass::do_something()
{
if ( !::_my_flag.test_and_set() ) )
{
// do my stuff here; handle errors and clear flag when done
try
{
// do my stuff here
}
catch ( ... )
{
// handle exception
}
::_my_flag.clear(); // clear my flag, we're done doing stuff
}
// else, we're already doing something in another thread, let's exit
} // do_something
Run Code Online (Sandbox Code Playgroud)
更新:根据以下建议更新代码,形成正确使用的正确模板std::atomic_flag.谢谢大家!
atomic_flag是一个非常低级别的构造,并不意味着广泛使用.也就是说,我相信你的用法正如你想要的那样,除非在特殊情况下清除旗帜.如果std::exception出现一个匹配的异常,则该标志不会被清除.
通常RAII应该用于此类事情.'R'通常代表'资源',但我喜欢Jon Kalb 使用 '责任'.设置标志后,您有责任在完成后清除标志,因此您应该使用RAII来确保履行职责.如果在特殊情况下你需要做的所有事情都可以通过这种方式完成,那么try/ catchpair就会消失.
if ( !std::atomic_flag_test_and_set( &::_my_flag ) )
{
flag_clearer x(&::_my_flag);
// do my stuff here
}
Run Code Online (Sandbox Code Playgroud)
但是你不需要flag_clearer自己写一个类型.相反,您可以简单地使用更高级别的构造,例如互斥锁和lock_guard:
namespace
{
std::mutex my_flag;
}
myclass::do_something()
{
if ( my_flag.try_lock() )
{
std::lock_guard<std::mutex> x(my_flag, std::adopt_lock);
// do my stuff here
}
// else, we're already doing something in another thread, let's exit
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6663 次 |
| 最近记录: |