战魂小筑

讨论群:309800774 知乎关注:http://zhihu.com/people/sunicdavy 开源项目:https://github.com/davyxu

   :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  249 随笔 :: 0 文章 :: 508 评论 :: 0 Trackbacks

我在工程里使用以下函数给线程设置一个方便调试的名称

    typedef struct tagTHREADNAME_INFO
    {
        DWORD dwType;        // must be 0x1000
        LPCSTR szName;        // pointer to name (in user addr space)
        DWORD dwThreadID;    // thread ID (-1=caller thread)
        DWORD dwFlags;        // reserved for future use, must be zero
    } THREADNAME_INFO;
 
    void SetThreadName( DWORD dwThreadID, LPCSTR szThreadName )
    {
        THREADNAME_INFO info;
        info.dwType = 0x1000;
        info.szName = szThreadName;
        info.dwThreadID = dwThreadID;
        info.dwFlags = 0;
 
          // Visit http://www.cppblog.com/sunicdavy for original article
        __try
        {
            RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (DWORD*)&info );
        }
        __except(EXCEPTION_CONTINUE_EXECUTION)
        {
            int a =1;
        }
    }

使用期间一直正常. 随着工程需求变化,我需要频繁的将一个被命名的线程创建工作一段时间后马上结束释放资源并重新创建,出现了死锁问题

死锁总是发生在主线程的Sleep或者是SetEvent两个WindowsAPI函数. 而且仅仅在Visual Studio 2008里调试时会发生死锁,脱离调试环境一切正常.

我开始打日志调试, 结果发现死锁前能够正常创建线程,但是线程函数根本没有调用进入.之后就在主线程Sleep处死锁了.

由于SetThreadName没有使用正规的API接口,而是使用抛异常方式, 而且线程名称应该只在Visual Studio IDE中才能显示, MSDN对RaiseException的描述里也有说明可以使用WaitForDebugEvent接收应用程序抛得异常.因此可以推断是SetThreadName造成的问题. 屏蔽SetThreadName,测试通过

posted on 2011-10-12 09:50 战魂小筑 阅读(2425) 评论(1)  编辑 收藏 引用 所属分类: 程序调试技术C++/ 编程语言操作系统

评论

# re: VC中使用SetThreadName引起的线程死锁 2011-10-18 23:21 陈梓瀚(vczh)
这个名称只被VC++的debugger看到,而且在set之后才attach process是没用的,我觉得你可以不干这件事情。  回复  更多评论
  


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理