Win32重置事件,如带有Boost C ++的同步类 [英] Win32 reset event like synchronization class with boost C++
问题描述
我需要一些使人联想起Win32重置事件的机制,可以通过具有WaitForSingleObject()和WaitForMultipleObjects()具有相同语义的函数检查该函数(目前仅需要..SingleObject()版本).但是我的目标是多个平台,所以我所拥有的只是boost :: threads(AFAIK).我上了下一堂课,想问一下潜在的问题以及它是否适合任务.预先感谢.
I need some mechanism reminiscent of Win32 reset events that I can check via functions having the same semantics with WaitForSingleObject() and WaitForMultipleObjects() (Only need the ..SingleObject() version for the moment) . But I am targeting multiple platforms so all I have is boost::threads (AFAIK) . I came up with the following class and wanted to ask about the potential problems and whether it is up to the task or not. Thanks in advance.
class reset_event
{
bool flag, auto_reset;
boost::condition_variable cond_var;
boost::mutex mx_flag;
public:
reset_event(bool _auto_reset = false) : flag(false), auto_reset(_auto_reset)
{
}
void wait()
{
boost::unique_lock<boost::mutex> LOCK(mx_flag);
if (flag)
return;
cond_var.wait(LOCK);
if (auto_reset)
flag = false;
}
bool wait(const boost::posix_time::time_duration& dur)
{
boost::unique_lock<boost::mutex> LOCK(mx_flag);
bool ret = cond_var.timed_wait(LOCK, dur) || flag;
if (auto_reset && ret)
flag = false;
return ret;
}
void set()
{
boost::lock_guard<boost::mutex> LOCK(mx_flag);
flag = true;
cond_var.notify_all();
}
void reset()
{
boost::lock_guard<boost::mutex> LOCK(mx_flag);
flag = false;
}
};
示例用法;
reset_event terminate_thread;
void fn_thread()
{
while(!terminate_thread.wait(boost::posix_time::milliseconds(10)))
{
std::cout << "working..." << std::endl;
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
}
std::cout << "thread terminated" << std::endl;
}
int main()
{
boost::thread worker(fn_thread);
boost::this_thread::sleep(boost::posix_time::seconds(1));
terminate_thread.set();
worker.join();
return 0;
}
编辑
我已经根据迈克尔·伯尔(Michael Burr)的建议修复了代码.我的非常简单"测试表明没有问题.
I have fixed the code according to Michael Burr's suggestions. My "very simple" tests indicate no problems.
class reset_event
{
bool flag, auto_reset;
boost::condition_variable cond_var;
boost::mutex mx_flag;
public:
explicit reset_event(bool _auto_reset = false) : flag(false), auto_reset(_auto_reset)
{
}
void wait()
{
boost::unique_lock<boost::mutex> LOCK(mx_flag);
if (flag)
{
if (auto_reset)
flag = false;
return;
}
do
{
cond_var.wait(LOCK);
} while(!flag);
if (auto_reset)
flag = false;
}
bool wait(const boost::posix_time::time_duration& dur)
{
boost::unique_lock<boost::mutex> LOCK(mx_flag);
if (flag)
{
if (auto_reset)
flag = false;
return true;
}
bool ret = cond_var.timed_wait(LOCK, dur);
if (ret && flag)
{
if (auto_reset)
flag = false;
return true;
}
return false;
}
void set()
{
boost::lock_guard<boost::mutex> LOCK(mx_flag);
flag = true;
cond_var.notify_all();
}
void reset()
{
boost::lock_guard<boost::mutex> LOCK(mx_flag);
flag = false;
}
};
推荐答案
您需要检查/修复的几件事(注意-我绝不是说这是唯一的事情-我只是快速浏览):
A few things that you'll want to check/fix (note - I'm by no means saying that these are the only things - I've only had a quick look):
-
在
-
,如果已为
auto_reset
设置了已发信号的事件,则不会重置:
wait()
函数中的in your
wait()
function, you don't reset on an already signaled event if it's set up forauto_reset
:
void wait()
{
boost::unique_lock<boost::mutex> LOCK(mx_flag);
if (flag) {
if (auto_reset) flag = false; // <-- I think you need this
return;
}
cond_var.wait(LOCK);
if (auto_reset)
flag = false;
}
在wait(const boost::posix_time::time_duration& dur)
中的
中,应在等待条件变量之前检查flag
.
in wait(const boost::posix_time::time_duration& dur)
you should check flag
before waiting on the condition variable.
,如果您等待条件变量,则可能需要重新检查该标志,以确保在此期间其他某个线程没有重置该事件.对于auto_reset事件尤其如此,即使在多个线程正在等待该事件的情况下,auto_reset事件也应仅释放一个侍者.
in both wait
functions, if you wait on the condition variable, you might need to recheck the flag to make sure that some other thread hasn't reset the event in the meantime. This is particularly true for auto_reset events which should only free up a single waiter even when multiple threads are waiting on the event.
这篇关于Win32重置事件,如带有Boost C ++的同步类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!