windows多线程基础(2):如何创建多线程CreateThread

发布于:2021-05-15 07:16:17

1.进程首先会创建主线程

当进程被初始化时,系统就要创建一个主线程。该线程与C运行期库的启动代码一道开始运行,启动代码则调用进入点函数(main),并且继续运行直到main函数返回,并且C运行期库的启动代码调用ExitProcess为止。

2.编写一个线程函数

创建线程时,需要指定代码的入口函数,线程从这个入口点开始运行,例如main函数是主线程的入口函数。






主线程中创建的window线程入口函数应该长成下面这个样子:



DWORD WINAPI ThreadProc(_In_ LPVOID lpParameter)
{
...
return 0;
}



线程函数在结尾处返回,此时线程终止运行,其堆栈的内存被释放,同时线程的内核对象的计数被递减。如果内核对象的使用计数为0,该对象就被撤销。










注意:


(1)线程函数只接受一个参数,若是需要传递多个参数的话,需要对多个参数进行封装(结构体或者类)。


(2)线程函数必须返回一个值,该值将成为该线程的退出代码。


(3)多个线程在访问全局变量或者静态变量时,可能存在访问冲突,需要注意线程间互斥和同步。




3. 创建线程函数

调用CreateThread创建线程,CreateThread函数原型为:



HANDLE WINAPI CreateThread(
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ SIZE_T dwStackSize,
_In_ LPTHREAD_START_ROUTINE lpStartAddress,
_In_opt_ LPVOID lpParameter,
_In_ DWORD dwCreationFlags,
_Out_opt_ LPDWORD lpThreadId
);



当调用CreateThread时,系统创建一个内核对象。该线程内核对象不是线程本身,而是操作系统用来管理线程的较小的数据结构。系统从进程的地址空间中分配内存,共线程的栈使用。由于线程运行的进程环境与创建线程的环境相同,因此单个进程中的多个线程能够很容易的通信。


注意:


虽然CreateThread函数是用来创建线程的windows函数,但是不应该调用该函数。应该使用_beginthreadex,稍后会讲解_beginthreadex的重要性。






参数:


lpThreadAttributes:指向SECURITY_ATTRIBUTES结构的指针,NULL表示默*踩粜浴wStackSize:指定线程的栈空间大小,0表示使用默认值1M,这个值在链接器中设定。保留地址空间的容量为栈设置一个上限,这样就可发现代码中的循环递归错误。lpStartAddress:线程函数地址。lpParameter:传递给线程函数的参数。dwCreationFlags:用于设定控制线程的其他标志,可以使0或者CREATE_SUSPENDED,0表示线程创建后可以立即进行调度,CREATE_SUSPENDED可以在系统创建并初始化县城后,暂定该线程的运行,这样就无法调度。lpThreadId:该参数输出新线程的ID,NULL表示不关心新建线程的ID。






说了这么多,以下是例子:


#include
#include

using namespace std;

DWORD WINAPI ThreadFunc(LPVOID lpParameter)
{
char* param = ( char*) lpParameter;
cout << param << endl;

return 0;
}

DWORD main(VOID )
{
DWORD IDThread;
HANDLE hThread;
DWORD ExitCode;
const char* ThreadParam = "hello, new thread";
hThread = CreateThread( NULL, // 使用默*踩粜
0, // 使用默认栈空间大小
( LPTHREAD_START_ROUTINE)ThreadFunc, // 线程函数
( LPVOID)ThreadParam, // 传递给线程函数的参数
0, // 创建后立即调度
&IDThread); // 返回的线程ID
if (hThread == NULL)
{
cerr << "Fail to create thread" << endl;
return -1;
}
WaitForSingleObject(hThread, INFINITE); // 等待线程结束
if (GetExitCodeThread(hThread, &ExitCode)) // 获取线程返回值
{
cout << "Thread[" << IDThread << "] exits code is: " <<
ExitCode << endl;
}

system( "pause");
return 0;
}



以上代码首先创建一个线程,然后等待线程结束,最后输出线程的返回值。运行结果:














明天继续关于线程退出的介绍,以及_beginthreadex的引入原因。排版真麻烦~

相关推荐

最新更新

猜你喜欢