首页 > 技术文章 > 02等待单个线程返回WaitForSingleObject

rock-cc 2018-08-04 16:41 原文

windows 多线程之等待线程返回

​ 多线程编程中,有时我们需要等待某一线程完成了特定的操作之后再继续做其他事情,要实现这个目的,可以使用 Windows API 函数 WaitForSingleObject,或者 WaitForMultipleObject。这两个函数都会等待 Object 被标记为有信号(signaled)时才返回。只要是 Windows 创建的 Object 都会被赋予一个状态量。如果 Object 被激活了,或者正在使用,那么该 Object 就是无信号,也就是不可用;另一方面,如果 Object 可用了,那么它就恢复有信号了。

一. WaitForSingleObject 等待单个线程返回

1. 函数原型
DWORD WINAPI WaitForSingleObject(
    _In_ HANDLE hHandle,
    _In_ DWORD dwMilliseconds
    );
2. 参数说明

第一个参数 hHandle 是对象的句柄,可以是一下几种:

  • Change notification

  • Console input

  • Event

  • Memory resource notification

  • Mutex

  • Process

  • Semaphore

  • Thread

  • Waitable timer

第二个参数 dwMilliseconds 为等待时间,以毫秒为单位。参数 dwMilliseconds 有两个具有特殊意义的值:0 和 INFINITE。若为 0,则该函数立即返回;若为 INFINITE,则线程一直被挂起,直到 hHandle 所指向的对象变为有信号状态为止。

3. 返回值
  • WAIT_ABANDONED 0x00000080 当 hHandle 为 Mutex 时,如果拥有 Mutex 的线程在结束时没有释放核心对象会引发此返回值。
  • WAIT_OBJECT_0 0x00000000 等待的对象处于有信号状态。
  • WAIT_TIMEOUT 0x00000102 等待超时。
  • WAIT_FAILED 0xFFFFFFFF 出现错误,可以通过 GetLastError 得到错误代码。
4. 示例

(1)参数 dwMilliseconds 为 0,则该函数立刻返回(不阻塞)。

#include <Windows.h>
#include <stdio.h>

DWORD WINAPI ThreadFunc(LPVOID P)
{
	Sleep(5000);
	printf("I am child thread,Pid = %d\n", GetCurrentThreadId());
	return 0;
}

int main()
{
	HANDLE hThread;
	hThread = CreateThread(NULL, 0, ThreadFunc, 0, 0, NULL);
	printf("I am main thread, Pid = %d\n", GetCurrentThreadId());
	//不等待,直接返回
	WaitForSingleObject(hThread, 0);
	return 0;
}

输出结果为:

image

(2)参数 dwMilliseconds  为 5000,等待 5 秒后返回。

#include <Windows.h>
#include <stdio.h>

DWORD WINAPI ThreadFunc(LPVOID P)
{
	printf("I am child thread,Pid = %d\n", GetCurrentThreadId());
	Sleep(10000);
	printf("The child thread quit, pid = %d \n", GetCurrentThreadId());
	return 0;
}

int main()
{
	HANDLE hThread;
	hThread = CreateThread(NULL, 0, ThreadFunc, 0, 0, NULL);
	printf("I am main thread, Pid = %d\n", GetCurrentThreadId());
	//等待 5s 后返回
	WaitForSingleObject(hThread, 5000);
	return 0;
}

输出结果为:

image

(3)参数 dwMilliseconds 为 INFINITE,则线程一直被挂起,直到 hHandle 所指向的对象变为有信号状态时为止。

#include <Windows.h>
#include <stdio.h>

DWORD WINAPI ThreadFunc(LPVOID P)
{
	printf("I am child thread,Pid = %d\n", GetCurrentThreadId());
	Sleep(10000);
	printf("The child thread quit, pid = %d \n", GetCurrentThreadId());
	return 0;
}

int main()
{
	HANDLE hThread;
	hThread = CreateThread(NULL, 0, ThreadFunc, 0, 0, NULL);
	printf("I am main thread, Pid = %d\n", GetCurrentThreadId());
	//线程一直被挂起,直到 hThread 有信号,即子线程返回
	WaitForSingleObject(hThread, INFINITE);
	return 0;
}

输出结果为:

image

推荐阅读