多线程完成多个任务

 

 

typedef struct _THREADINOF
{
  BOOL *bExitFlag;  //退出标志(共用)
  HANDLE hExitEvent; //退出事件(共用)
  HANDLE hRunEvent; //运行事件
  HANDLE hDoneEvent; //运行完成事件
  BOOL bThreadIsRuning; //线程运行中
  UINT uThreadIndex; //线程索引
  UINT uTaskID; //任务ID
  LPCRITICAL_SECTION lpCriticalSection; //临界区

  //…… 其它信息
}THREADINOF;

UINT ThreadFunction(LPVOID lParam)
{
  THREADINOF *pThreadInfo = (THREADINOF*)lParam;
  //参数检查
  ASSERT(pThreadInfo);
  ASSERT(pThreadInfo->bExitFlag);
  ASSERT(pThreadInfo->hExitEvent);
  ASSERT(pThreadInfo->hRunEvent);
  ASSERT(pThreadInfo->hDoneEvent);

  //……其它初始化工作

  while(pThreadInfo)
  {
    //等待事件
    HANDLE hMultEvent[] = {pThreadInfo->hExitEvent, pThreadInfo->hRunEvent};
    switch(WaitForMultipleObjects(2, hMultEvent, FALSE, INFINITE))
    {
    case(WAIT_OBJECT_0)://exit event
      {
        return -1;
      }
    case(WAIT_OBJECT_0 + 1)://run event
      {
        break;
      }
    default://error
      {
        ASSERT(FALSE);
        break;
      }
    }

    pThreadInfo->bThreadIsRuning = TRUE; //线程运行中
    BOOL bTreadDone = FALSE;
    for(;(!bTreadDone) && (*pThreadInfo->bExitFlag == 0);)
    {      
      //……线程运行代码

      //模拟某些长时间的操作
      {
        Sleep(rand()/32);
      }

      //某些必须的临界区操作
      if(pThreadInfo->lpCriticalSection)
        EnterCriticalSection(pThreadInfo->lpCriticalSection);

      //临界区代码
      TRACE(_T("Thead(%u) Task(%u)\n"),
        pThreadInfo->uThreadIndex,
        pThreadInfo->uTaskID);

      //退出临界区
      if(pThreadInfo->lpCriticalSection)
        LeaveCriticalSection(pThreadInfo->lpCriticalSection);

      if(1)//满足线程任务完成条件
      {
        bTreadDone = TRUE;
        break; //跳出循环
      }
      else//为其它线程留出时间
      {
        Sleep(100);
        //SwitchToThread();//切换线程
      }
    }

    //线程运行完成,通知父进程
    {
      SetEvent(pThreadInfo->hDoneEvent);
      pThreadInfo->bThreadIsRuning = FALSE;//线程结束
    }
  }

  return 0;
}

void RunTask()
{
#define MAX_THREAD_NUM 4//最多线程数
  BOOL bTreadExitFlag = FALSE; //线程退出标志
  HANDLE hExitEvent = CreateEvent(NULL, TRUE, FALSE, NULL); //线程退出事件
  HANDLE hRunEvent[MAX_THREAD_NUM] = {0};//通知线程运行事件
  HANDLE hDoneEvent[MAX_THREAD_NUM] = {0};//线程运行完成事件
  THREADINOF ThreadInfo[MAX_THREAD_NUM] = {0};
  HANDLE hThread[MAX_THREAD_NUM] = {0};
  CRITICAL_SECTION mCriticalSection;
  InitializeCriticalSection(&mCriticalSection);

  //创建线程
  {
    for(int i=0; i<MAX_THREAD_NUM; i++)
    {
      VERIFY(hRunEvent[i] = CreateEvent(NULL, FALSE, FALSE, NULL));
      VERIFY(hDoneEvent[i] = CreateEvent(NULL, TRUE, TRUE, NULL));

      ThreadInfo[i].uThreadIndex = i;
      ThreadInfo[i].bExitFlag = &bTreadExitFlag;
      ThreadInfo[i].hExitEvent = hExitEvent;
      ThreadInfo[i].hRunEvent = hRunEvent[i];
      ThreadInfo[i].hDoneEvent = hDoneEvent[i];
      ThreadInfo[i].lpCriticalSection = &mCriticalSection;
      //……其它参数

      hThread[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFunction, &ThreadInfo[i], 0, NULL);
      ASSERT(hThread[i]);
    }
  }

  //运行线程  
  UINT uTaskID = 0;
  BOOL bOverFlag = FALSE;
  while(1)
  {
    if(bOverFlag) //任务结束
    {
      WaitForMultipleObjects(MAX_THREAD_NUM, hDoneEvent, TRUE, INFINITE);//等待所有线程结束
      break;
    }
    else //执行任务
    {
      DWORD dwWait = WaitForMultipleObjects(MAX_THREAD_NUM, hDoneEvent, FALSE, INFINITE);
      if(dwWait >= (WAIT_OBJECT_0 + MAX_THREAD_NUM))
      {
        ASSERT(FALSE);
      }
      else
      {
        int iThread = dwWait;
        if(uTaskID < 100) //有新任务可以分配
        {
          //分配新任务
          //ThreadInfo[i].xxx 设置新参数
          ThreadInfo[iThread].uTaskID = uTaskID++; //

          ResetEvent(ThreadInfo[iThread].hDoneEvent); //复位就绪事件
          SetEvent(ThreadInfo[iThread].hRunEvent); //激活线程          
        }
        else//所有任务完成
        {
          bOverFlag = TRUE;
        }
      }
    }
  }

  //结束线程
  {
    bTreadExitFlag = TRUE;
    SetEvent(hExitEvent);

    WaitForMultipleObjects(MAX_THREAD_NUM, hThread, TRUE, INFINITE);
  }

  //清理工作
  {
    #define DoCloseHandle(h) do{ if(h)CloseHandle(h); h=NULL; }while(0);
    DoCloseHandle(hExitEvent);
    for(int i=0; i<MAX_THREAD_NUM; i++)
    {
      DoCloseHandle(hRunEvent[i]);
      DoCloseHandle(hDoneEvent[i]);
    }

    DeleteCriticalSection(&mCriticalSection);
  }

}


//调试输出
Thead(2) Task(2)
Thead(3) Task(3)
Thead(1) Task(1)
Thead(0) Task(0)
Thead(3) Task(5)
Thead(2) Task(4)
Thead(1) Task(6)
Thead(0) Task(7)
Thead(1) Task(9)
Thead(2) Task(8)
Thead(3) Task(10)
Thead(0) Task(11)
Thead(1) Task(12)
Thead(2) Task(13)
Thead(0) Task(15)
Thead(3) Task(14)
Thead(1) Task(16)
Thead(2) Task(17)
Thead(0) Task(18)
Thead(3) Task(19)
Thead(1) Task(20)
Thead(0) Task(21)
Thead(3) Task(23)
Thead(2) Task(22)
Thead(1) Task(24)
Thead(0) Task(25)
Thead(3) Task(27)
Thead(2) Task(26)
Thead(1) Task(28)
Thead(3) Task(31)
Thead(0) Task(29)
Thead(2) Task(30)
Thead(1) Task(32)
Thead(2) Task(35)
Thead(0) Task(33)
Thead(3) Task(34)
Thead(1) Task(36)
Thead(3) Task(39)
Thead(0) Task(37)
Thead(2) Task(38)
Thead(1) Task(40)
Thead(0) Task(41)
Thead(3) Task(43)
Thead(2) Task(42)
Thead(1) Task(44)
Thead(3) Task(47)
Thead(0) Task(45)
Thead(2) Task(46)
Thead(1) Task(48)
Thead(0) Task(49)
Thead(2) Task(51)
Thead(3) Task(50)
Thead(1) Task(52)
Thead(3) Task(55)
Thead(0) Task(53)
Thead(2) Task(54)
Thead(1) Task(56)
Thead(3) Task(57)
Thead(0) Task(58)
Thead(2) Task(59)
Thead(1) Task(60)
Thead(3) Task(61)
Thead(0) Task(62)
Thead(2) Task(63)
Thead(1) Task(64)
Thead(3) Task(65)
Thead(0) Task(66)
Thead(2) Task(67)
Thead(1) Task(68)
Thead(3) Task(69)
Thead(0) Task(70)
Thead(2) Task(71)
Thead(1) Task(72)
Thead(3) Task(73)
Thead(0) Task(74)
Thead(2) Task(75)
Thead(1) Task(76)
Thead(3) Task(77)
Thead(0) Task(78)
Thead(2) Task(79)
Thead(1) Task(80)
Thead(3) Task(81)
Thead(0) Task(82)
Thead(2) Task(83)
Thead(1) Task(84)
Thead(3) Task(85)
Thead(0) Task(86)
Thead(2) Task(87)
Thead(1) Task(88)
Thead(1) Task(92)
Thead(3) Task(89)
Thead(0) Task(90)
Thead(2) Task(91)
Thead(1) Task(93)
Thead(3) Task(94)
Thead(0) Task(95)
Thead(2) Task(96)
Thead(3) Task(98)
Thead(0) Task(99)
Thead(1) Task(97)
线程 'Win32 线程' (0xcd4) 已退出,返回值为 -1 (0xffffffff)。
线程 'Win32 线程' (0xe58) 已退出,返回值为 -1 (0xffffffff)。
线程 'Win32 线程' (0xf94) 已退出,返回值为 -1 (0xffffffff)。
线程 'Win32 线程' (0xce4) 已退出,返回值为 -1 (0xffffffff)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值