c++ - Win32 重置事件,如带有 boost C++ 的同步类

标签 c++ multithreading synchronization cross-platform autoresetevent

我需要一些让人想起 Win32 重置事件的机制,我可以通过与 WaitForSingleObject() 和 WaitForMultipleObjects() 具有相同语义的函数来检查(目前只需要 ..SingleObject() 版本)。但我的目标是多个平台,所以我只有 boost::threads (AFAIK) 。我想出了下面的类(class),想问一下潜在的问题,以及它是否能胜任这项任务。提前致谢。

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 的建议修复了代码。我的“非常简单”的测试表明没有问题。

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;
    }
};

最佳答案

您需要检查/修复的几件事(注意 - 我绝不是说这些是唯一的事情 - 我只是快速浏览了一下):

  • 在您的 wait() 函数中,如果为 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 before 等待条件变量.

  • 在两个 wait 函数中,如果您等待条件变量,您可能需要重新检查标志以确保其他线程在此期间没有重置事件。对于 auto_reset 事件尤其如此,即使多个线程正在等待该事件,它也应该只释放一个等待者。

关于c++ - Win32 重置事件,如带有 boost C++ 的同步类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4692717/

相关文章:

c++ - 如何使用 C/C++ 在 OS X 中获取分区偏移量?

android - 蓝牙:程序卡在 connect() 方法

c++ - 条件变量死锁

time - Windows 服务器上的 PTP 同步(与 Linux 相比)- 可以保证什么精度

iphone - 重复调用webservice, objective-c

c++ - 为什么我在声明中收到 "not declared in scope"错误?

c++ - 在此示例中使用空基类是否合理?

c++ - 使用结构模板的结构模板

C++11 引入了标准化的内存模型。这是什么意思?它将如何影响 C++ 编程?

multithreading - SetEvent ResetEvent WaitForMultipleObjectsEx-竞赛条件?