WINAPI 多线程二

等待一个内核对象变为已通知状态(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: 退出码

  1. 可以让线程调用ExitThread函数,以便强制线程终止运行。

  2. 使用这个函数退出线程,不会执行线程函数的return语句。

  3. 不调用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;
}

 

注:均为自己学习时所做记录 方便日后查阅

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值