boost::this_thread::sleep_for()会死锁

(金庆的专栏)

发现睡眠1ms很容易死锁。
boost::this_thread::sleep_for(boost::chrono::milliseconds(1)).

Boost 1.54.0

以下代码很可能重现死锁:

#include "stdafx.h"

#include <iostream>
#include <boost/thread.hpp>

using namespace std;

void worker()
{
    for (int i = 0; i < 10000; i++)
        boost::this_thread::sleep_for(boost::chrono::milliseconds(1));
}

int _tmain(int argc, _TCHAR* argv[])
{
    boost::thread_group tg;
    for (int i = 0; i < 30; i++)
        tg.create_thread(worker);

    tg.join_all();
    cout << "All done!" << endl;
    return 0;
}

附加到死锁进程调试时,调用栈如下:
boost::this_thread::interruptible_wait() Line 547
boost::detail::basic_cv_list_entry::wait() Line 94
boost::detail::basic_condition_variable::do_wait<>() Line 228
boost::condition_variable::wait_until<>() Line 371
boost::this_thread::sleep_until<>() Line32
boost::this_thread::sleep_for<>() Line72
worker()
boost::detail::thread_data<>()

程序在停在thread.cpp:547:
    unsigned long const notified_index=detail::win32::WaitForMultipleObjects(handle_count, handles, false, using_timer?INFINITE:time_left.milliseconds);
其中    
handle_count = 2
using_timer = false
time_left.milliseconds = 0xfffffffe

发现 basic_cv_list_entry::wait(timeout abs_time) 当 abs_time.milliseconds = uint64(-1) 时就会死锁.
所在可以在此断点,将 abs_time.milliseconds 改为 uint64(-1),就可以重现死锁了.

实际上该参数很可能输入为-1:
        wait_until(...)
        {
          do_wait(lock, ceil<milliseconds>(t-Clock::now()).count());
          ...
        }

这几天改服务器代码,添加了许多 sleep_for(), 结果就经常发现服务器停止响应了。
幸好该错误仅在Windows上存在。错误位于 boost/thread/win32/condition_variable.hpp.

正准备给Boost添加条Bug记录,发现该错误已在3周前报告,10天前已修正,将在1.55.0版本中发布。
见:
Condition variable will wait forever for some timepoint values (MSVC)    
https://svn.boost.org/trac/boost/ticket/9079

修正代码如下:

    chrono::time_point<Clock, Duration> now = Clock::now();
    if (t<=now) {
      return cv_status::timeout;
    }
    do_wait(lock, ceil<milliseconds>(t-now).count());

boost::this_thread::sleep_for()死锁的更多相关文章

  1. 错误 4 error C2039: “Sleep”: 不是“boost::this_thread”的成员

    检查是否是在x64下运行的. #include <pcl/io/openni2_grabber.h> #include <pcl/visualization/cloud_viewer ...

  2. boost和C++11中的sleep

    boost boost线程中表示睡眠的函数有sleep和sleep_for sleep 例如: boost::this_thread::sleep(boost::posix_time::seconds ...

  3. (十)boost库之多线程

    (十)boost库之多线程 1.创建线程 使用boost库可以方便的创建一个线程,并提供最多支持9个参数的线程函数,相对于void*来说,方便了很多,创建线程主要提供了一下3种方式: 线程库头文件:# ...

  4. http客户端-基于boost开发

    http客户端-基于boost开发 基于BOOST编写的http客户端,作为BOOST开发学习之用.目前支持功能: http协议,单向链接返回http response code 200 可conte ...

  5. BOOST学习笔记

    BOOST学习笔记 1 tool #pragma once #include <vector> #include "boost/noncopyable.hpp" #in ...

  6. Debug EOS:nodeos + mongo_db_plugin

    上文书说到区块链的存储方式,并结合了EOSIO进行分析,其中也提到了使用CLion调试EOS的方法.本文将继续深入细致地展开对加载了mongo_db_plugin的nodeos的调试过程以及心得. 关 ...

  7. c++并发编程之条件变量(Condition Variable)

    条件变量(Condition Variable)的一般用法是:线程 A 等待某个条件并挂起,直到线程 B 设置了这个条件,并通知条件变量,然后线程 A 被唤醒.经典的「生产者-消费者」问题就可以用条件 ...

  8. 搞定thrift双向消息

    thrift作为脱胎于facebook的rpc框架,各方面都非常优秀.清晰的分层设计,多语言的支持,以及不输protocolbuffer的效率(compact下优于protocolbuffer),都让 ...

  9. std::this_thread::yield/sleep_for

    std::this_thread::yield(): 当前线程放弃执行,操作系统调度另一线程继续执行.. std::this_thread::sleep_for(): 表示当前线程休眠一段时间,休眠期 ...

随机推荐

  1. Android中FrameAnimation动画的使用

    Frame Animation 表示帧动画,是顺序播放事先做好的图像,跟电影类似,Android SDK提供了另外一个类AnimationDrawable来定义使用Frame Animation. 下 ...

  2. 【Unity Shaders】Alpha Test和Alpha Blending

    写在前面 关于alpha的问题一直是个比较容易摸不清头脑的事情,尤其是涉及到半透明问题的时候,总是不知道为什么A就遮挡了B,而B明明在A前面.这篇文章就总结一下我现在的认识~ Alpha Test和A ...

  3. RMI方式Ehcache集群的源码分析

    Ehcache不仅支持基本的内存缓存,还支持多种方式将本地内存中的缓存同步到其他使用Ehcache的服务器中,形成集群.如下图所示: Ehcache支持多种集群方式,下面以RMI通信方式为例,来具体分 ...

  4. Cocos2D iOS之旅:如何写一个敲地鼠游戏(四):创建TexturePacker自动脚本

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...

  5. Cocos2D iOS之旅:如何写一个敲地鼠游戏(二):Cocos2D中的高清支持

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...

  6. 【Unity Shaders】Transparency —— 使用alpha通道创建透明效果

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  7. 【一天一道LeetCode】#108. Convert Sorted Array to Binary Search Tree

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...

  8. 最简单的基于FFmpeg的AVDevice例子(读取摄像头)

    =====================================================最简单的基于FFmpeg的AVDevice例子文章列表: 最简单的基于FFmpeg的AVDev ...

  9. Linux多线程实践(10) --使用 C++11 编写 Linux 多线程程序

    在这个多核时代,如何充分利用每个 CPU 内核是一个绕不开的话题,从需要为成千上万的用户同时提供服务的服务端应用程序,到需要同时打开十几个页面,每个页面都有几十上百个链接的 web 浏览器应用程序,从 ...

  10. PA 创建项目

    ---- 创建项目 DECLARE l_orig_project_id NUMBER := 6; l_prj_num VARCHAR2(240) := 'CXYTEST001'; l_start_da ...