关于多线程的一些细节
来源:互联网 发布:为什么帅哥配丑女 知乎 编辑:程序博客网 时间:2024/04/28 15:45
关于多线程的一些细节
作者: 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-
可以执行以下代码:
CMainFrame*frm=(CMainFrame*)(AfxGetApp()-
frm-
另外:注意需要捕捉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
{
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]
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=3537
- 关于多线程的一些细节
- 关于多线程的一些细节
- 关于多线程的一些细节
- 关于多线程的一些细节
- 关于C++的一些细节
- 关于string的一些细节
- 关于deque的一些细节
- 关于javascript的一些细节
- 关于textfield的一些细节
- 关于myBatis的一些细节
- 关于split的一些细节
- 关于mysql的procedure的一些细节
- 关于C++的一些细节[一]
- 关于.net类的一些小细节
- 关于文本域的一些细节~~~~~~~
- 关于slub分配器的一些细节
- 关于QPushButton的一些小细节
- webservices关于处理的一些细节
- 如何调用浏览路径对话框
- 微软项目管理软件的二次开发
- 谈VC++中的Progress控件的使用
- SSL加密3389远程桌面连接
- NIMDA病毒危害及清除和免疫
- 关于多线程的一些细节
- 在WIN95中实现文件拷贝的编程方法
- VC++中的一个不足及其改善方法
- 使用临界段实现优化的进程间同步对象-原理和实现
- Beta 1 到 Beta 2 改变详细列表(英文)
- 多屏幕显示器编程( 一 )
- 重学JS
- Redirecting Standard Input/Output using the Process Class
- Printing out your W2 Form using C# and .NET