欢迎来到天天文库
浏览记录
ID:34488036
大小:27.28 KB
页数:15页
时间:2019-03-06
《线程四个状态及临界区》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库。
1、Windows提供了多组支持多线程的应用程序接口(API)函数。许多读者已经对Windows提供的多线程函数有一定程度的了解,但是对于那些不熟悉这些的读者,本章提供了这些函数的概述。记住,Windows提供了许多其他的基于多线程的函数,这些函数需要您自己去探索。为了使用Windows的多线程函数,必须在程序中包含。3.4.1线程的创建和终止WindowsAPI提供了CreateThread()函数来创建一个线程。其原型如下所示:HANDLECreateThread(LPSECURITY_ATTRIBUTESsecAttr,SIZE
2、_TstackSize,LPTHREAD_START_ROUTINEthreadFunc,LPVOIDparam,DWORDflags,LPDWORDthreadID);在此,secAttr是一个用来描述线程的安全属性的指针。如果secAttr是NULL,就会使用默认的安全描述符。每个线程都具有自己的堆栈。可以使用stackSize参数来按字节指定新线程堆栈的大小。如果这个整数值为0,那么这个线程堆栈的大小与创建它的线程相同。如果需要的话,这个堆栈可以扩展。(通常使用0来指定线程堆栈的大小)。每个线程都在创建它的进程中通过调用线程函数来开始执行。线程的
3、执行一直持续到线程函数返回。这个函数的地址(也就是线程的入口点)在threadFunc中指定。每个线程函数都必须具有这样的原型:DWORDWINAPIthreadfunc(LPVOIDparam);需要传递给新线程的任何参数都在CreateThread()的param中指定。线程函数在它的参数中接收这个32位的值。这个参数可以用作任何目的。函数返回它的退出状态。参数flags确定了线程的执行状态。如果它是0,线程会立即执行。如果是CREATE_SUSPEND,线程则以挂起状态创建并等待执行。(可以通过调用ResumeThread()来开始执行,稍后讨论
4、)。与线程相关的标识符以threadID所指向的长整型返回。如果成功,函数则向线程返回一个句柄。如果失败,则返回NULL。可以通过调用CloseHandle()来显式销毁这个线程。否则,会在父进程结束时自动销毁它。如前所述,当线程的入口函数返回时终止执行线程。进程也可以使用TerminateThread()或者ExitThread()来手动终止线程,这两个函数的原型如下:BOOLTerminateThread(HANDLEthread,DWORDstatus);VOIDExitThread(DWORDstatus);对于TerminateThread(
5、),thread是将要终止的线程的句柄。ExitThread()只能用来终止调用了ExitThread()的线程。对于两个函数而言,status是终止状态。TerminateThread()如果成功,则会返回非0值,否则返回0。调用ExitThread()在功能上等价于允许线程函数正常返回。这意味着堆栈会正确地重新设置。当使用TerminateThread()结束线程时,线程会立刻终止,而会执行任何特定的清理任务。另外,TerminateThread()可能会停止正在执行重要操作的线程。为此,当入口函数返回时,通常最好(也是最容易的)让线程正常终止。3
6、.4.2VisualC++对CreateThread()和ExitThread()的替换尽管CreateThread()和ExitThread()是用来创建并终止线程的WindowsAPI函数,我们在本章并不会使用它们。原因是在VisualC++中(其他的Windows兼容的编译器也可能有这个问题)使用这两个函数时,会导致内存泄漏,丢失少量的内存。对于VisualC++,如果多线程程序利用了C/C++标准库函数并使用了CreateThread()和ExitThread(),就会丢失少量的内存。(如果您的程序没有使用C/C++的标准库,就不会发生这样的内
7、存丢失)。为了避免这种情况,必须使用VisualC++运行库中定义的函数来开始和终止线程,而不是使用由Win32API指定的函数。这些函数类似于CreateThread()和ExitThread(),但是不会产生内存泄漏。提示:如果使用非VisualC++的编译器,如果需要的话,检查它的文档来确定是否需要忽略CreateThread()和ExitThread(),以及如何做到这一点。VisualC++用_beginthreadex()和_endthreadex()来取代CreateThread()和ExitThread()。这两个函数都需要头文件8、ocess.h>。下面是_beginthreadex()函数的原型:uintptr_t_beg
8、ocess.h>。下面是_beginthreadex()函数的原型:uintptr_t_beg
此文档下载收益归作者所有