Win32重置事件,如带有Boost C ++的同步类 [英] Win32 reset event like synchronization class with boost C++

查看:106
本文介绍了Win32重置事件,如带有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):

    wait()函数中的
  • ,如果已为auto_reset设置了已发信号的事件,则不会重置:

  • in your wait() function, you don't reset on an already signaled event if it's set up for auto_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屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆