Chinaunix首页 | 论坛 | 博客
  • 博客访问: 352120
  • 博文数量: 43
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 585
  • 用 户 组: 普通用户
  • 注册时间: 2013-03-29 20:57
文章分类

全部博文(43)

文章存档

2013年(43)

我的朋友

分类: C/C++

2013-05-21 14:17:39

    最近在做UPS的历史记录下载小软件,涉及到多线程同步的问题,由于之前对MFC的线程部分一直没怎么好好理解,所以在这个点上着实磨破脑皮。网上谈到最多的方法是WaitForSingleObject,但无论wait的对象是线程本身,还是某个在线程执行函数结束时signaled的事件,均会对主线程造成阻塞,在等待的线程结束前界面卡死,不能达到想要的效果。
    终于找到一篇文章给我诸多启发,文章原文如下,摘自:http://blog.csdn.net/smilestone322/article/details/7724995

点击(此处)折叠或打开

  1. void WaitForThreadExit(void)
  2. {
  3.  DWORD dwRet;
  4.  MSG msg;
  5.  int wait_count=4;
  6.  int nExitThreadCount=0;

  7.  while(1)
  8.  {
  9.   dwRet = MsgWaitForMultipleObjects(wait_count, hArray, FALSE, INFINITE, QS_ALLINPUT);

  10.   if (dwRet == WAIT_OBJECT_0 + wait_count)
  11.   {
  12.    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  13.    {
  14.     if (msg.message==WM_QUIT||msg.message==WM_CLOSE)
  15.     {
  16.     
  17.      break;
  18.     }

  19.     TranslateMessage(&msg);
  20.     DispatchMessage(&msg);
  21.    }
  22.   }else if (dwRet >= WAIT_OBJECT_0 && dwRet < WAIT_OBJECT_0+ wait_count)
  23.   {
  24.    nExitThreadCount++;
  25.    if (nExitThreadCount < 4)
  26.    {

  27.     TRACE("一个线程退出了n");

  28.     int nIndex=dwRet-WAIT_OBJECT_0;

  29.     hArray[nIndex]=hArray[wait_count-1];

  30.     hArray[wait_count-1]=NULL;
  31.     wait_count--;
  32.    }else
  33.    {
  34.     TRACE("4个线程都退出了n");
  35.   
  36.     break;
  37.    }
  38.   }else
  39.   {
  40.    DWORD dErrCode=GetLastError();
  41.  
  42.    break;
  43.   }

  44.  }
  45. }
    将该函数稍做修改,即可比较灵活的应用到我们的工程,贴出自己的一个小demo如下:

点击(此处)折叠或打开

  1. //等待多线程结束
  2. void WaitForThreadExit(int count, HANDLE* hArray)
  3. {
  4.  DWORD dwRet;
  5.  MSG msg;
  6.  int wait_count=count;
  7.  int nExitThreadCount=0;

  8.  while(1)
  9.  {
  10.   dwRet = MsgWaitForMultipleObjects(wait_count, hArray, FALSE, INFINITE, QS_ALLINPUT);

  11.   if (dwRet == WAIT_OBJECT_0 + wait_count)
  12.   {
  13.    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  14.    {
  15.     if (msg.message==WM_QUIT||msg.message==WM_CLOSE)
  16.     {
  17.     
  18.      break;
  19.     }

  20.     TranslateMessage(&msg);
  21.     DispatchMessage(&msg);
  22.    }
  23.   }else if (dwRet >= WAIT_OBJECT_0 && dwRet < WAIT_OBJECT_0+ wait_count)
  24.   {
  25.    nExitThreadCount++;
  26.    if (nExitThreadCount < wait_count)
  27.    {

  28.     TRACE("一个线程退出了n");

  29.     int nIndex=dwRet-WAIT_OBJECT_0;

  30.     hArray[nIndex]=hArray[wait_count-1];

  31.     hArray[wait_count-1]=NULL;
  32.     wait_count--;
  33.    }else
  34.    {
  35.     TRACE("4个线程都退出了n");
  36.   
  37.     break;
  38.    }
  39.   }else
  40.   {
  41.    DWORD dErrCode=GetLastError();
  42.  
  43.    break;
  44.   }

  45.  }
  46. }

  47. //定义事件对象
  48. CEvent cEvent1=NULL;
  49. CEvent cEvent2=NULL;

  50. void CwaitForMutiThreadCloseDlg::OnBnClickedButton1()
  51. {
  52.     // TODO: 在此添加控件通知处理程序代码
  53.     AfxBeginThread(ThreadFunc1,NULL);//启动线程
  54.     AfxBeginThread(ThreadFunc2,NULL);//启动线程

  55.     HANDLE hArray[2]={cEvent1,cEvent2};
  56.     WaitForThreadExit(2,hArray);

  57.     int i=0;
  58.     i++;
  59. }

  60. UINT CwaitForMutiThreadCloseDlg::ThreadFunc1(LPVOID lParam)
  61. {
  62.     for(int i=0;i<10000;i++)
  63.     {
  64.         TRACE("%dn",i);
  65.     }
  66.     cEvent1.SetEvent();
  67.     return 0;
  68. }

  69. UINT CwaitForMutiThreadCloseDlg::ThreadFunc2(LPVOID lParam)
  70. {
  71.     for(int i=10000;i>0;i--)
  72.     {
  73.         TRACE("%dn",i);
  74.     }
  75.     cEvent2.SetEvent();
  76.     return 0;
  77. }


阅读(2844) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~