通过前一篇文章,我们已经知道可以通过GetExitCodeThread 来不断获取线程状态确定线程是否已经结束。
这种方法叫做busy loop或者busy wait。但是这种方法并不好,因为它会浪费CPU 可用时间。
只有一两个线程这样去等待还可以,但是如果有成千上百个线程这样去等待的话,CPU的资源将被等待占用,而实际工作的CPU资源将所剩无几。
所以我们需要另外一种等待方式
DWORD WINAPI WaitForSingleObject(
_In_ HANDLE hHandle,
_In_ DWORD dwMilliseconds
);
具体参考MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx
同时等待多个线程结束可以使用WaitForMultipleObjects
DWORD WINAPI WaitForMultipleObjects(
_In_ DWORD nCount,
_In_ const HANDLE *lpHandles,
_In_ BOOL bWaitAll,
_In_ DWORD dwMilliseconds
);
具体参考MSDN: https://msdn.microsoft.com/en-us/library/ms687025(VS.85).aspx
该API 返回值比较复杂(以下说明来自《Win32 多线程程序设计》)
1. 如果因时间终了而返回,则返回值是WAIT_TIMEOUT, 类似WaitForSingleObject()。
2. 如果bWaitAll是TRUE, 那么返回值将是WAIT_OBJECT_0。
3. 如果bWaitAll是FALSE, 那么将返回值减去WAIT_OBJECT_0,就是表示数组中的哪一个handle被激发了。(激发就是线程结束了)
4. 如果你等待的对象中有任何mutexes, 那么返回值可能从WAIT_ABANDONED_0 到 WAIT_ABANDONED_0 + nCount - 1。
5. 如果函数失败,它会传回WAIT_FAILED. 这时候你可以使用GetLastError() 找出失败的原因。
运行结果:
这种方法叫做busy loop或者busy wait。但是这种方法并不好,因为它会浪费CPU 可用时间。
只有一两个线程这样去等待还可以,但是如果有成千上百个线程这样去等待的话,CPU的资源将被等待占用,而实际工作的CPU资源将所剩无几。
所以我们需要另外一种等待方式
DWORD WINAPI WaitForSingleObject(
_In_ HANDLE hHandle,
_In_ DWORD dwMilliseconds
);
具体参考MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx
WaitForSingleObject 不仅可以等待线程,还可以等待文件I/O操作,互斥器(Mutexes)等等。
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
using namespace std;
DWORD WINAPI ThreadFunc(LPVOID);
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hThread1 = NULL;
HANDLE hThread2 = NULL;
DWORD dwThreadId1 = 0;
DWORD dwThreadId2 = 0;
//DWORD dwExitCode1 = 0;
//DWORD dwExitCode2 = 0;
hThread1 = CreateThread(0,0,ThreadFunc,(LPVOID)1,0,&dwThreadId1);
if (hThread1)
{
cout<<"Thread1 started"<<endl;
}
hThread2 = CreateThread(0,0,ThreadFunc,(LPVOID)2,0,&dwThreadId2);
if (hThread2)
{
cout<<"Thread2 started"<<endl;
}
WaitForSingleObject(hThread1,INFINITE);
cout<<"Thread1 is over"<<endl;
WaitForSingleObject(hThread2,INFINITE);
cout<<"Thread2 is over"<<endl;
//for (;;)
//{
// cout<<"Press any key to exit"<<endl;
// getchar();
// GetExitCodeThread(hThread1,&dwExitCode1);
// GetExitCodeThread(hThread2,&dwExitCode2);
// if (dwExitCode1 == STILL_ACTIVE)
// {
// cout<<"Thread1 is working"<<endl;
// }
// if (dwExitCode2 == STILL_ACTIVE)
// {
// cout<<"Thread2 is working"<<endl;
// }
// if (dwExitCode1 != STILL_ACTIVE
// && dwExitCode2 != STILL_ACTIVE)
// {
// cout<<"All threads finished"<<endl;
// break;
// }
//}
if (hThread1)
{
CloseHandle(hThread1);
}
if (hThread2)
{
CloseHandle(hThread2);
}
//cout<<"Thread1 exit with "<<dwExitCode1<<endl;
//cout<<"Thread2 exit with "<<dwExitCode2<<endl;
system("PAUSE");
return 0;
}
DWORD WINAPI ThreadFunc(LPVOID n)
{
int j = (int)n;
for (int i=0;i<10;i++)
{
Sleep(j*1000);
cout<<j<<endl;
if (j == 1 && i == 1)
{
ExitThread(4);
}
}
return 0;
}
同时等待多个线程结束可以使用WaitForMultipleObjects
DWORD WINAPI WaitForMultipleObjects(
_In_ DWORD nCount,
_In_ const HANDLE *lpHandles,
_In_ BOOL bWaitAll,
_In_ DWORD dwMilliseconds
);
具体参考MSDN: https://msdn.microsoft.com/en-us/library/ms687025(VS.85).aspx
该API 返回值比较复杂(以下说明来自《Win32 多线程程序设计》)
1. 如果因时间终了而返回,则返回值是WAIT_TIMEOUT, 类似WaitForSingleObject()。
2. 如果bWaitAll是TRUE, 那么返回值将是WAIT_OBJECT_0。
3. 如果bWaitAll是FALSE, 那么将返回值减去WAIT_OBJECT_0,就是表示数组中的哪一个handle被激发了。(激发就是线程结束了)
4. 如果你等待的对象中有任何mutexes, 那么返回值可能从WAIT_ABANDONED_0 到 WAIT_ABANDONED_0 + nCount - 1。
5. 如果函数失败,它会传回WAIT_FAILED. 这时候你可以使用GetLastError() 找出失败的原因。
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
using namespace std;
#define THREAD_POOL_SIZE 3
#define HANDLE_MAX_INDEX THREAD_POOL_SIZE - 1
#define MAX_TASK_NUMBER 6
DWORD WINAPI ThreadFunc(LPVOID);
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hThread[THREAD_POOL_SIZE];
DWORD dwThreadId = 0;
int iIndex = 0;
for (int i=1; i<= MAX_TASK_NUMBER; i++)
{
if (i>THREAD_POOL_SIZE)
{
DWORD dwRet = WaitForMultipleObjects(THREAD_POOL_SIZE,
hThread,
FALSE,
INFINITE);
iIndex = dwRet - WAIT_OBJECT_0;
cout<<"Thread "<<iIndex+1<<" is end."<<endl;
CloseHandle(hThread[iIndex]);
}
hThread[iIndex++] = CreateThread(0,0,ThreadFunc,(LPVOID)iIndex,0,&dwThreadId);
cout<<"Thread "<<iIndex<<" started"<<endl;
}
WaitForMultipleObjects(THREAD_POOL_SIZE,
hThread,
TRUE,
INFINITE);
for (int i=0;i<THREAD_POOL_SIZE;i++)
{
CloseHandle(hThread[i]);
}
cout<<"All Thread end"<<endl;
system("PAUSE");
return 0;
}
DWORD WINAPI ThreadFunc(LPVOID n)
{
int j = (int)n;
srand(GetTickCount());
Sleep((rand()%10)*800+500);
cout<<"Thread "<<j+1<<" is idle"<<endl;
return 0;
}
运行结果: