如何设置并发::事件对象,仅当它现在未处于信号状态时
How to set Concurrency::event object only if it is not in signaled state now?
在我的代码中,只有当特殊事件未处于信号状态时,某些并发工作任务才应该开始工作。代码示例:
tasks.run([&](){
if (event.wait(0)!=0)
{
event.set();
// work code ...
}
})
此类任务可能有许多实例,只有一个实例应该工作。但是wait()和set()是不同的方法,代码不是原子的。因此,可能是两个或多个任务实例开始工作的情况。我如何测试事件的信号状态并仅在非信号时锁定它,并以原子方式进行?
看起来你可以使用mutex::try_lock
代码应如下所示:
tasks.run([&](){ if (event.wait(0)!=0 && mutex.try_lock()) { event.set(); mutex.unlock(); 工作代码... }})
不要忘记确保 event.set() 不会抛出异常,否则需要额外的努力来使此代码异常安全。
也许你应该把整个包装成 while (true) 来捕获"假阳性"案例,就像这样:
tasks.run([&](){ 而(真) { if (event.wait(0)!=0 && mutex.try_lock()) { event.set(); mutex.unlock(); 工作代码... 破; } }});
因此,未能获取锁的任务将返回到等待状态。
我的解决方案:
安全设置事件类:
namespace Concurrency {
class event_safe : public event
{
public:
inline bool try_set()
{
critical_section::scoped_lock locker(m_lock);
bool bRes = (wait(0)==Concurrency::COOPERATIVE_WAIT_TIMEOUT);
if (bRes)
set();
return bRes;
}
protected:
critical_section m_lock;
};
}
工作代码:
tasks.run([&](){
if (event.try_set()) {
// work code ...
}
})
相关文章:
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- Qt VTK交互风格的信号到小部件
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- c++r值引用应用于函数指针
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- 如果编译的源代码是特定于它编译的硬件的,我们如何分发它
- 为什么这会过早地存在于西吉尔信号中
- 信号处理程序和本地状态
- QTreeView模型的Qt-itemChanged信号仅适用于一级项目
- Microsoft相当于WebkitGTK悬停在链接上的信号
- 如何设置并发::事件对象,仅当它现在未处于信号状态时
- 当使用信号处理程序触发事件时,如何使boost.msm正确更改状态
- Qt QState机器同步问题:初始状态未在启动信号上设置
- QT C++ - 信号和插槽:"No such slot QLabel..."甚至插槽功能也存在于我的类中
- 为什么 std::生成类似于 std::for_each 的返回状态?
- 应用于嵌入式状态机的设计
- 序列化具有特定于环境状态的多态类
- 如何在Qt中检查信号状态
- 如何确定 Win32 事件的信号状态
- 在Linux/ c++中,发送给线程/进程的信号是否使其变为活动状态?