加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

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

发布时间:2020-12-14 05:30:06 所属栏目:Windows 来源:网络整理
导读:我需要一些让人想起Win32重置事件的机制,我可以通过具有与WaitForSingleObject()和WaitForMultipleObjects()相同语义的函数来检查(暂时只需要..SingleObject()版本).但我的目标是多个平台,所以我只有boost :: threads(AFAIK).我想出了下面的课程,想要询问潜
我需要一些让人想起Win32重置事件的机制,我可以通过具有与WaitForSingleObject()和WaitForMultipleObjects()相同语义的函数来检查(暂时只需要..SingleObject()版本).但我的目标是多个平台,所以我只有boost :: threads(AFAIK).我想出了下面的课程,想要询问潜在的问题以及是否能胜任.提前致谢.

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

>在等待(const boost :: posix_time :: time_duration& dur)你应该在等待条件变量之前检查标志.>在两个等待函数中,如果等待条件变量,则可能需要重新检查该标志以确保其他某个线程在此期间未重置该事件.对于auto_reset事件尤其如此,即使多个线程正在等待事件,它也应该只释放一个服务员.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读