加载中…
个人资料
南冠彤
南冠彤
  • 博客等级:
  • 博客积分:0
  • 博客访问:414,747
  • 关注人气:59
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
相关博文
推荐博文
谁看过这篇博文
加载中…
正文 字体大小:

(转)UI线程与WORK线程的纠缠

(2011-06-03 09:53:08)
标签:

杂谈

分类: CPP/C

最近写了个多线程,在WORK线程(子线程)函数里有对窗口更新的操作,这样导致在执行子线程时会主动跳转到UI线程执行,而非正常的线程调度。

子线程的退出由UI线程控制,主要是设置一个FLAG,当为TRUE时子线程就知道我该退出了,但UI线程还需要知道子线程是否成功退出,这里我使用了WaitForSingleObject()等待子线程HANDLE,如果等待超时,则强行结束子线程,经过调试发现,无论如何等待thread handle都是超时,最后强行结束了子线程。看代码:
FLAG = TRUE;
WaitForSingleObject(...); // 导致UI线程阻塞,切换到子线程执行,而由于子线程会对窗口更新,也因UI线程的阻塞而导致子线程阻塞,所以子线程永远无法退出,而UI线程也就一直等待,直到超时,如果等待是无限期的,则程序陷入僵局,也就发生了死锁。

因此多线程中,如果UI线程要控制子线程的进退,而子线程又会时不时主动转移到UI线程上来执行,则在UI线程中最好不要使用WaitForSingleObject(),而改为子线程退出时给UI线程发消息,通知我已经正常退出了。

当然也有别的方法来判断子线程是否成功退出。


 

 

 

谨防work线程和UI线程共用锁导致死锁

 

比如下面所示的代码:

#define UPDATE_MYLISTCTRL (WM_USER + 10)
CListCtrl m_listCtrl;

ON_MESSAGE(UPDATE_MYLISTCTRL,OnUpdateListCtrl)

void CMyDialog::OnBnClickedButton1()
{
//启动work线程,往ListCtrl里添加80000条Item
boost::thread thread(boost::bind(&CMyDialog::WorkThreadFun,this,80000));
}

void CMyDialog::OnDestroy()
{
{
boost::mutex::scoped_lock lock(m_lock);//UI线程请求锁
//...其它操作
}
CDialog::OnDestroy();
}

void CMyDialog::WorkThreadFun(int count)
{
{
boost::mutex::scoped_lock lock(m_lock);//work线程请求锁
for(int i = 0; i < count; ++i)
{
//...其它操作
//通知往ListCtrl里加Item
::SendMessage(m_hWnd, UPDATE_MYLISTCTRL, NULL, NULL);
 
}
}

LRESULT CMyDialog::OnUpdateListCtrl(WPARAM,LPARAM)
{
//...往ListCtrl里增加新Item等更新UI操作
return 0L;
}

在上面的例子中,由于需要往ListCtrl里添加大量数据,为了防止界面等待,使用一个work线程在后台做它。如果在线程函数退出之前用户点击关闭窗口,那么UI线程将进入CMyDialog::OnDestroy()函数,当执行到boost::mutex::scoped_lock lock(m_lock)这行,UI线程试图得到锁;假定此时work线程执行到::SendMessage(m_hWnd, UPDATE_MYLISTCTRL, NULL, NULL)这行,试图给UI线程发送更新通知消息,由于SendMessage是同步调用,它必须等待消息处理函数执行完毕才能返回,也即是希望UI线程开始执行OnUpdateListCtrl函数,而此时UI线程正在OnDestroy()函数里等待work线程解锁,这里死锁就发生了。

在这种情况下,一个勉强可以的办法是用PostMessage函数代替SendMessage函数,因为PostMessage函数是立即返回的,那么work线程也就立即解锁了,UI线程OnDestroy函数得到锁继续执行;但是有另一个问题是可能OnDestroy执行完了,才开始试图执行OnUpdateListCtrl,而此时窗口已经被Destroy掉了。


因此,在UI线程和work线程里不要共用锁,以防死锁;需要锁的话也要分开,即UI线程和work线程各自用独立的锁,不要混用。

书籍推荐:多线程编程技术大全

0

阅读 评论 收藏 转载 喜欢 打印举报/Report
后一篇:(转)IOCP
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

    后一篇 >(转)IOCP
      

    新浪BLOG意见反馈留言板 电话:4000520066 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有