抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

创建在调用进程的虚拟地址空间内执行的线程。
若要创建在另一个进程的虚拟地址空间中运行的线程,请使用CreateRemoteThread函数。

函数声明

1
2
3
4
5
6
7
8
9
10
11
12
WINBASEAPI
_Ret_maybenull_
HANDLE
WINAPI
CreateThread(
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ SIZE_T dwStackSize,
_In_ LPTHREAD_START_ROUTINE lpStartAddress,
_In_opt_ __drv_aliasesMem LPVOID lpParameter,
_In_ DWORD dwCreationFlags,
_Out_opt_ LPDWORD lpThreadId
);

参数

lpThreadAttributes

指向SECURITY_ATTRIBUTES结构的指针, 该结构确定是否可由子进程继承返回的句柄。如果lpThreadAttributesNULL, 则无法进程句柄;

dwStackSize

堆栈的初始大小(以字节为单位)。系统将此值舍入到最近的页面。如果此参数为零, 则新线程将使用可执行文件的默认大小;

lpStartAddress

指向要由线程执行的应用程序定义函数的指针。此指针表示线程的起始地址;

  • lpStartAddress函数原型
    1
    2
    3
    DWORD WINAPI ThreadProc(
    _In_ LPVOID lpParameter
    );

lpParameter

指向要传递给线程的变量的指针;

dwCreationFlags

控制线程的标志

含义
0 线程在创建后立即运行
CREATE_SUSPENDED 0x00000004 线程以挂起状态创建, 在调用ResumeThread函数之前不会运行
STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000 dwStackSize参数指定堆栈的初始保留大小。如果未指定此标志, dwStackSize将指定提交大小

lpThreadId

指向接收线程标识符的变量的指针。如果此参数为NULL, 则不返回线程标识符;

返回值

如果函数成功, 则返回值是新线程的句柄;
如果函数失败, 则返回值为NULL;

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
DWORD WINAPI ThreadFirstProc(LPVOID lpParameter)
{
WCHAR wcBuffer[20]{};
DWORD dwTimer = 0;
::GetWindowText((HWND)lpParameter, wcBuffer, 20);
WCHAR wcValue[20]{};
int iValue = _wtoi(wcBuffer);
while (iValue > 0)
{
wsprintf(wcValue, L"%d", --iValue);
::SetWindowText((HWND)lpParameter, wcValue);
Sleep(1000);
}
return 0;

}

DWORD WINAPI ThreadSecondProc(LPVOID lpParameter)
{
WCHAR wcBuffer[20]{};
DWORD dwTimer = 0;
::GetWindowText((HWND)lpParameter, wcBuffer, 20);
WCHAR wcValue[20]{};
int iValue = _wtoi(wcBuffer);
while (iValue >= 0)
{
wsprintf(wcValue, L"%d", ++iValue);
::SetWindowText((HWND)lpParameter, wcValue);
Sleep(1000);
}
return 0;
}

CWnd* pWndFirst = GetDlgItem(IDC_EDIT1);
HWND hWndFirst = pWndFirst->GetSafeHwnd();
CWnd* pWndSecond = GetDlgItem(IDC_EDIT2);
HWND hWndSecond = pWndSecond->GetSafeHwnd();
HANDLE hThreadFirst = ::CreateThread(NULL, 0, ThreadFirstProc, hWndFirst, 0, NULL);
HANDLE hThreadSecond = ::CreateThread(NULL, 0, ThreadSecondProc, hWndSecond, 0, NULL);

WaitForSingleObject

功能说明

等待函数可使线程自愿进入等待状态, 直到一个特定的内核对象变为已通知状态为止;

函数声明

1
2
3
4
5
6
7
WINBASEAPI
DWORD
WINAPI
WaitForSingleObject(
_In_ HANDLE hHandle, // handle to object
_In_ DWORD dwMilliseconds // time-out interval
);

参数说明

hHandle

内核对象句柄, 可以是进程也可以是线程;

dwMilliseconds

等待时间, 单位是毫秒; INFINITE(-1)一直等待;

返回值

  • WAIT_OBJECT_0(0); 等待对象变为已通知;
  • WAIT_TIMEOUT(0x102); 超时;

特别说明

  1. 内核对象中的每种对象都可以说是处于已通知或未通知的状态之中;
  2. 这种状态的切换是由Microsoft为每个对象建立的一套规则来决定的;
  3. 当线程正在运行的时候, 线程内核对象处于未通知状态;
  4. 当线程终止运行的时候, 它就变为已通知状态;
  5. 在内核中就是个BOOL值, 运行时FALSE, 结束TRUE;

代码演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
DWORD WINAPI ThreadProc1(LPVOID lpParameter)	
{
for(int i=0;i<5;i++)
{
printf("+++++++++\n");
Sleep(1000);
}
return 0;
}

int main(int argc, char* argv[])
{
//创建一个新的线程
HANDLE hThread1 = ::CreateThread(NULL, 0, ThreadProc1,
DWORD dwCode = ::WaitForSingleObject(hThread1, INFINITE);
MessageBox(0,0,0,0);
return 0;
}

WaitForMultipleObjects

功能说明

同时查看若干个内核对象的已通知状态;

函数声明

1
2
3
4
5
6
7
8
9
WINBASEAPI
DWORD
WINAPI
WaitForMultipleObjects(
_In_ DWORD nCount,
_In_reads_(nCount) CONST HANDLE* lpHandles,
_In_ BOOL bWaitAll,
_In_ DWORD dwMilliseconds
);

参数说明

nCount

要查看内核对象的数量;

lpHandles

内核对象数组

bWaitAll

等待类型; TRUE: 等待所有变为已通知, FALSE: 只要有一个变为已通知;

dwMilliseconds

超时时间; INFINITE一直等待;

返回值

  • bWaitAll为TRUE时, 返回WAIT_OBJECT_0(0)代码所有内核对象都变为已通知;
  • bWaitAll为FALSE时, 返回最先变成已通知的内核对象在数组中的索引;
  • WAIT_TIMEOUT(0x102), 超时;

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
DWORD WINAPI ThreadProc1(LPVOID lpParameter)							
{
for(int i=0;i<5;i++)
{
printf("+++++++++\n");
Sleep(1000);
}
return 0;
}

DWORD WINAPI ThreadProc2(LPVOID lpParameter)
{
for(int i=0;i<3;i++)
{
printf("---------\n");
Sleep(1000);
}
return 0;
}


int main(int argc, char* argv[])
{

HANDLE hArray[2];
//创建一个新的线程
HANDLE hThread1 = ::CreateThread(NULL, 0, ThreadProc1,
NULL, 0, NULL);

//创建一个新的线程
HANDLE hThread2 = ::CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);
hArray[0] = hThread1;
hArray[1] = hThread2;
DWORD dwCode = ::WaitForMultipleObjects(2, hArray,FALSE,INFINITE);
MessageBox(0,0,0,0);
return 0;
}

评论