最近在做UPS的历史记录下载小软件,涉及到多线程同步的问题,由于之前对MFC的线程部分一直没怎么好好理解,所以在这个点上着实磨破脑皮。网上谈到最多的方法是WaitForSingleObject,但无论wait的对象是线程本身,还是某个在线程执行函数结束时signaled的事件,均会对主线程造成阻塞,在等待的线程结束前界面卡死,不能达到想要的效果。
终于找到一篇文章给我诸多启发,文章原文如下,摘自:
http://blog.csdn.net/smilestone322/article/details/7724995
点击(此处)折叠或打开
-
void WaitForThreadExit(void)
-
{
-
DWORD dwRet;
-
MSG msg;
-
int wait_count=4;
-
int nExitThreadCount=0;
-
-
while(1)
-
{
-
dwRet = MsgWaitForMultipleObjects(wait_count, hArray, FALSE, INFINITE, QS_ALLINPUT);
-
-
if (dwRet == WAIT_OBJECT_0 + wait_count)
-
{
-
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
-
{
-
if (msg.message==WM_QUIT||msg.message==WM_CLOSE)
-
{
-
-
break;
-
}
-
-
TranslateMessage(&msg);
-
DispatchMessage(&msg);
-
}
-
}else if (dwRet >= WAIT_OBJECT_0 && dwRet < WAIT_OBJECT_0+ wait_count)
-
{
-
nExitThreadCount++;
-
if (nExitThreadCount < 4)
-
{
-
-
TRACE("一个线程退出了n");
-
-
int nIndex=dwRet-WAIT_OBJECT_0;
-
-
hArray[nIndex]=hArray[wait_count-1];
-
-
hArray[wait_count-1]=NULL;
-
wait_count--;
-
}else
-
{
-
TRACE("4个线程都退出了n");
-
-
break;
-
}
-
}else
-
{
-
DWORD dErrCode=GetLastError();
-
-
break;
-
}
-
-
}
-
}
将该函数稍做修改,即可比较灵活的应用到我们的工程,贴出自己的一个小demo如下:
点击(此处)折叠或打开
-
//等待多线程结束
-
void WaitForThreadExit(int count, HANDLE* hArray)
-
{
-
DWORD dwRet;
-
MSG msg;
-
int wait_count=count;
-
int nExitThreadCount=0;
-
-
while(1)
-
{
-
dwRet = MsgWaitForMultipleObjects(wait_count, hArray, FALSE, INFINITE, QS_ALLINPUT);
-
-
if (dwRet == WAIT_OBJECT_0 + wait_count)
-
{
-
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
-
{
-
if (msg.message==WM_QUIT||msg.message==WM_CLOSE)
-
{
-
-
break;
-
}
-
-
TranslateMessage(&msg);
-
DispatchMessage(&msg);
-
}
-
}else if (dwRet >= WAIT_OBJECT_0 && dwRet < WAIT_OBJECT_0+ wait_count)
-
{
-
nExitThreadCount++;
-
if (nExitThreadCount < wait_count)
-
{
-
-
TRACE("一个线程退出了n");
-
-
int nIndex=dwRet-WAIT_OBJECT_0;
-
-
hArray[nIndex]=hArray[wait_count-1];
-
-
hArray[wait_count-1]=NULL;
-
wait_count--;
-
}else
-
{
-
TRACE("4个线程都退出了n");
-
-
break;
-
}
-
}else
-
{
-
DWORD dErrCode=GetLastError();
-
-
break;
-
}
-
-
}
-
}
-
-
//定义事件对象
-
CEvent cEvent1=NULL;
-
CEvent cEvent2=NULL;
-
-
void CwaitForMutiThreadCloseDlg::OnBnClickedButton1()
-
{
-
// TODO: 在此添加控件通知处理程序代码
-
AfxBeginThread(ThreadFunc1,NULL);//启动线程
-
AfxBeginThread(ThreadFunc2,NULL);//启动线程
-
-
HANDLE hArray[2]={cEvent1,cEvent2};
-
WaitForThreadExit(2,hArray);
-
-
int i=0;
-
i++;
-
}
-
-
UINT CwaitForMutiThreadCloseDlg::ThreadFunc1(LPVOID lParam)
-
{
-
for(int i=0;i<10000;i++)
-
{
-
TRACE("%dn",i);
-
}
-
cEvent1.SetEvent();
-
return 0;
-
}
-
-
UINT CwaitForMutiThreadCloseDlg::ThreadFunc2(LPVOID lParam)
-
{
-
for(int i=10000;i>0;i--)
-
{
-
TRACE("%dn",i);
-
}
-
cEvent2.SetEvent();
-
return 0;
-
}
阅读(2887) | 评论(0) | 转发(0) |