关于多线程的一些细节

原创 2001年09月24日 11:33:00

关于多线程的一些细节


                          作者: coolnerd


  线程的程序中,如果线程要向界面窗口报告状态,有两种操作方法,
一种是通过消息的方法,由于消息本身携带的消息量有时不购用,往往消息参数
只是一个指向某消息对象的指针,而消息对象往往需要在堆内存中new生成,

(因为往往线程不能等待消息处理完毕就继续执行,所以如果消息对象是栈对象
往往消息对象还未来及被处理,就又被线程修改.所以采用堆对象.)

界面接受到
消息对象后delete之.但是这时界面退出后,如果线程仍然生成新的消息对象,
则消息对象得不到释放,所以在这种情况下,界面接受到WM_CLOSE消息将要释放
之前,要等待线程完全退出之后再真正释放.

线程向界面报告状态的第二种方法是直接在线程的执行过程中同步地(等待,
直到完成称为同步)执行界面显示,这种机制下,要注意在界面显示是需要查看
界面窗口是否仍然存在(使用IsWindow(hWnd)函数实现).
这样做似乎已经完美,但是是不完善的,因为假如有多个view小窗口,如多个
CSplitterWnd,只在一个CSplitterWnd的WM_CLOSE消息的处理函数中进行防范,
其他的CSplitterWnd照常退出,仍然要出问题,所以要抓住根源:

用户使用菜单退出或点击frmae窗口的x按钮退出,接受到退出消息的首先是frameWnd
所以需要在frameWnd的WM_CLOSE函数中进行线程的释放.!
另外,往往线程在Document类的掌管之下,frame怎样访问document对象?
FrameWnd没有直接提供获取document的函数.Document,View,FrameWnd三者的
创建顺序是:doc->Frmae->View,在View::InitUpdate()函数的执行时刻,
可以执行以下代码:
CMainFrame*frm=(CMainFrame*)(AfxGetApp()->m_pMainWnd);
frm->pDoc=GetDocument();
另外:注意需要捕捉WM_CLOSE,而非WM_DESTROY消息,因为WM_CLOSE消息
先于后者.

另外,考查以下代码:
void CThreadList::UpdateThread(int id,CString client,CString msg)
{
EnterCriticalSection(&CThreadList::csUpDateThread);
{
int ItemCount=m_ListCtrl.GetItemCount() ; //ListCtrl
最多65535条记录
if(id>ItemCount)
{
for(int i=0;i<id-ItemCount;i++)
{
LV_ITEM lvi;

lvi.mask = LVIF_TEXT | LVIF_IMAGE
/* |LVIF_STATE */;
lvi.iItem = ItemCount+i;
lvi.iSubItem = 0;
m_ListCtrl.InsertItem(&lvi);
//m_ListCtrl.SetItemCount(id);
}
}

m_ListCtrl.SetItemText(id-1,0,ito10a(id));
m_ListCtrl.SetItemText(id-1,1,client);
m_ListCtrl.SetItemText(id-1,2,msg);
}
LeaveCriticalSection(&CThreadList::csUpDateThread);
}
这就是线程用来调用的界面函数,该界面CThreadList
是个ListCtrl类,该成员函数的参数中,id,client,msg是界面显示的内容
函数首先判断id是否超出现在已经存在的个数,如果超出则增加一到多条记录
这种动态调整记录个数的机制比较诱人,但是如果这个函数是在这样的情况下
被调用: frame窗口接受到了WM_CLOSE消息,在处理消息之前,首先消灭线程
而就在消灭线程的过程中,一个未来及消灭的线程调用了这个函数,该函数在
执行过程中需要执行GetItemCount()函数,跟踪GetItemCount函数,发现它是
依靠执行SendMessage获得ItemCount的(SendMessage函数是个不等到结果不
返回的函数),这时会发生的是死机,因为Windows系统在处理WM_ClOSE消息
未完成时,又被要求处理SendMessage函数,于是SendMessage函数和WM_CLOSE
消息处理过程发生了互相等待的事故.
结论是不要在线程向界面报告状态的过程中调用任何依靠消息工作的函数.
经过考查,几乎所有更新界面控件的函数如SetItemText都是依靠SendMessage
来工作的,所以会到问题的最初:"在多线程的程序中,如果线程要向界面窗口
报告状态,有两种操作方法"在这两种方法中,第二种方法是行不通的.
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 166.111.60.81]

<scrIPT language=JavaScript1.2 src="../article_bottom.js">

关于多线程的一些细节

2001年09月24日 11:33:00 关于多线程的一些细节 作者: coolnerd 线程的程序中,如果线程要向界面窗口报告状态,有两种操作方法...
  • softart
  • softart
  • 2007年10月27日 12:32
  • 191

HTTP协议细节

一】客服端  -->  服务端        1》结构            a)请求行            b)请求头            c)请求体:请求的内容,如果没有,就是空白字符    ...
  • u012986057
  • u012986057
  • 2016年01月23日 16:42
  • 330

strcpy函数细节

char * strcpy(char *dest,char *sour);c  = strcpy(a,b)a只能是空间足够大的字符串数据对象,比如说数组。a的空间不够大,将导致越界,不产生异常,但修改...
  • strayer555
  • strayer555
  • 2006年12月10日 15:31
  • 383

移动App运营推广的13个细节

安卓渠道运营要关注哪些内容? 1、渠道的玩法和规则 知道每家渠道的玩法、相关规则(活动和首发) 开发者后台帮助文档 渠道排名规则:下载量、评论的权重 2、市场最近动态 渠道的开发者...
  • m13295105247
  • m13295105247
  • 2018年01月29日 14:22
  • 33

JAVA经典及细节总结

写代码: 1,明确需求。我要做什么?    分析的时候:从具体到抽象 2,分析思路。我要怎么做?1,2,3。 实现的时候:从抽象到具体 3,确定步骤。每一个思路部分用到哪些语句,方法,和对象。 ...
  • sinat_24196195
  • sinat_24196195
  • 2015年11月12日 21:39
  • 1382

从零基础成为深度学习高手——Ⅱ

今天继续昨天的知识,继续学习新的一个阶段知识: 深度学习基础知识   接下来我们了解一下基础知识,我们上面也提到了,我们这次主要以卷积神经网络在图像识别领域的应用来介绍深度学习的,卷积...
  • gzq0723
  • gzq0723
  • 2017年12月12日 16:24
  • 255

日军偷袭珍珠港的一些细节——兼评1970和2001年版电影

 1. 机动舰队在夏威夷时间1941年12月7日晨3:30到达预定地点——珍珠港以北200海里。当时风大浪急,一些浪头甚至能够打到航空母舰的甲板上。我们从两部电影中都看不到这一天气状况的反映。由于这一...
  • myan
  • myan
  • 2004年04月26日 11:02
  • 9491

一些时间类型的总结

1. 系统时间函数         在编程时,时间函数不可避免的会被使用。linux系统下相关时间的数据结构有time_t,timeval,timespec,tm,clock_t; windows下...
  • pud_zha
  • pud_zha
  • 2013年10月01日 01:52
  • 825

对时间的一些操作总结

由于项目要对时间进行一些数学运算,要使用 access 数据库交互一些时间的信息,于是乎便有了下文。。。 CTime Comparison OperatorsBOOL operator ==( CTi...
  • xum2008
  • xum2008
  • 2010年09月08日 17:15
  • 461

矩阵的一些操作

 /***********************typedef.h***************/#define TRUE               1#define FALSE         ...
  • yingcongxiao
  • yingcongxiao
  • 2005年01月14日 11:18
  • 1328
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于多线程的一些细节
举报原因:
原因补充:

(最多只允许输入30个字)