等待一个内核对象变为已通知状态(single 单个)
DWORD WaitForSingleObject(HANDLE hObject,DWORD dwMilliseconds);
hObject: 指明一个内核对象的句柄(线程句柄)
dwMilliseconds:等待时间 毫秒数
备注:
1.函数需要传递一个内核(或线程)对象句柄。
2.如果该内核对象处于未通知状态,则该函数导致线程进入阻塞状态。(线程未结束)
3.如果该内核对象处于已通知状态,则该函数立即返回WAIT_OBJECT_0。(线程已结束)
4.第二个参数指明要等待的时间(毫秒),INFINITE表示无限等待。
5.如果第二个参数为0,那么函数立即返回。
6.如果等待超时,该函数返回WAIT_TIMEOUT。
7.如果失败, 返回WAIT_FAILED。
终止线程
最佳方式: 让它的线程函数return返回。
避免使用: ExitThread();
必须避免: TerminateThread();
ExitThread():(线程内部)
VOID ExitThread(DWORD dwExitCode); dwExitCode: 退出码
-
可以让线程调用ExitThread函数,以便强制线程终止运行。
-
使用这个函数退出线程,不会执行线程函数的return语句。
-
不调用return,就不会调用线程函数作用域内申请的类对象的析构函数,会造成内存泄漏。
TerminateThread():(线程外)
BOOL TerminateThread(HANDLE hThread, DWORD dwExitCode);
hThread: 被终止的线程句柄
dwExitCode: 退出码
备注:
1.在线程外终止一个线程,用于强制终止线程。
2.成功:返回非0。
3,失败:返回0,可调用GetLastError()获取原因。
注:
1.TerminateThread能够撤销任何线程。
2.线程的内核对象的使用记数也被递减。
3.该函数是异步运行的函数,当函数返回时,并不能保证线程被撤销。
4.需要确切的直到该线程已经终止运行,可使用WaitForSingleObject或类似函数。
5.windows核心编程:一个设计良好的应用程序决不会使用这个函数, 因为被终止运行的线程收不到它被“杀死”的通知,导致线程不能正确的清除。
获取线程结束码
BOOL GetExitCodeThread(HANDLE hThread, LPDWORD lpExitCode);
hThread: 由CreateThread()传回的线程handle句柄
lpExitCode: 指向一个DWORD,用于接收结束代码
备注:
1.成功:返回TRUE。
2.失败:返回FALSE,可以调用GetLastError()找出原因。
3.如果线程已结束,那么线程的结束代码会被放在lpExitCode参数中带回来。
4.如果线程尚未结束,lpExitCode带回来的值是STILL_ACTIVE.
5.在调用该函数之前,注意不要调用CloseHandle关闭掉线程句柄。
6.该函数可以在调用WaitForSingleObject()等待线程结束之后再调用。(线程不会阻塞)
等待多个内核对象变为已通知状态
DWORD WaitForMultipleObjects(
DWORD dwCount,
CONST HANDLE* phObjects,
BOOL bWaitAll,
DWORD dwMilliseconds);
dwCount: 等待的内核对象个数
phObjects: 一个存放被等待的内核对象句柄的数组
bWaitAll: 是否等到所有内核对象为已通知状态后才返回
dwMilliseconds: 等待时间(毫秒)
备注:
1.该函数的第一个参数指明等待的内核对象的个数,可以是0到MAXIMUM_WAIT_OBJECTS(64)中的一个值。
2.bWaitAll如果为TRUE, 则只有当等待所有内核对象为已通知状态时函数才返回。
3.bWaitAll如果为FALSE,则只要一个内核对象为已知状态,则该函数返回该函数在其数组对象中的位置。
返回值:
失败:返回WAIT_FAILED
超时:返回WAIT_TIMEOUT
bWaitAll参数为TRUE 函数成功:返回WAIT_OBJECT_0
bWaitAll参数为FALSE函数成功:返回数组的索引指明是哪个内核对象收到通知。
#include <windows.h>
#include <iostream>
using namespace std;
DWORD WINAPI ThreadFun(LPVOID lpThreadParameter);
int main()
{
DWORD threadid;
cout << "主线程开头" << endl;
HANDLE thread = CreateThread(NULL, 0, ThreadFun, NULL, 0, &threadid);
DWORD code;
//获取退出码
GetExitCodeThread(thread, &code);
if (code = STILL_ACTIVE) //未退出返回STILL_ACTIVE
{
cout << "子线程未退出" << endl;
}
//等待主线程运行3S
DWORD result = WaitForSingleObject(thread, 3000);
if (result == WAIT_TIMEOUT)
{
cout << "子线程等待超时" << endl;
TerminateThread(thread, 888);
}
//无限等待,除非子线程运行结束(阻塞)
WaitForSingleObject(thread, INFINITE);
//获取退出码
GetExitCodeThread(thread, &code);
cout << "子线程的退出码为:" << code << endl;
cout << "主线程结尾" << endl;
return 0;
}
DWORD WINAPI ThreadFun(LPVOID lpThreadParameter)
{
int i = 0;
while (++i<=5)
{
cout << "第"<<i<<"子线程hello!" << endl;
Sleep(1000);
//if (i == 3)
// ExitThread(1);
}
return 0;
}
#include<windows.h>
#include<iostream>
using namespace std;
DWORD WINAPI ThreadFun(LPVOID name);
int main()
{
cout << "主线程开始!" << endl;
HANDLE handle1 = CreateThread(NULL, 0, ThreadFun, "A", 0, NULL);
HANDLE handle2 = CreateThread(NULL, 0, ThreadFun, "B", 0, NULL);
HANDLE handle3 = CreateThread(NULL, 0, ThreadFun, "C", 0, NULL);
HANDLE handlearry[] = { handle1 ,handle2 ,handle3 };
//true 为等待至所有线程退出 false 为其中一个退出
DWORD ret = WaitForMultipleObjects(3, handlearry,false, INFINITE);
if (ret == 0)
{
cout << "所有线程都已退出!" << endl;
}
else
{
cout << ret << "退出!" << endl;
}
cout << "主线程退出!" << endl;
return 0;
}
DWORD WINAPI ThreadFun(LPVOID name)
{
char * pname = (char*)name;
if (strcmp(pname, "A") == 0)
{
Sleep(10000);
}
else if (strcmp(pname, "B") == 0)
{
Sleep(8000);
}
else
{
Sleep(5000);
}
cout << pname << "线程退出!" << endl;
return 0;
}
注:均为自己学习时所做记录 方便日后查阅