科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件深入浅出Win32多线程程序设计之线程控制

深入浅出Win32多线程程序设计之线程控制

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

WIN32线程控制主要实现线程的创建、终止、挂起和恢复等操作,这些操作都依赖于WIN32提供的一组API和具体编译器的C运行时库函数。

作者:宋宝华 来源:天极开发 2007年10月16日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
2.创建线程

  进程的主线程由操作系统自动生成,Win32提供了CreateThread API来完成用户线程的创建,该API的原型为:

HANDLE CreateThread(
 LPSECURITY_ATTRIBUTES lpThreadAttributes,//Pointer to a SECURITY_ATTRIBUTES structure
 SIZE_T dwStackSize, //Initial size of the stack, in bytes.
 LPTHREAD_START_ROUTINE lpStartAddress,
 LPVOID lpParameter, //Pointer to a variable to be passed to the thread
 DWORD dwCreationFlags, //Flags that control the creation of the thread
 LPDWORD lpThreadId //Pointer to a variable that receives the thread identifier
);

  如果使用C/C++语言编写多线程应用程序,一定不能使用操作系统提供的CreateThread API,而应该使用C/C++运行时库中的_beginthread(或_beginthreadex),其函数原型为:

uintptr_t _beginthread(
 void( __cdecl *start_address )( void * ), //Start address of routine that begins execution of new thread
 unsigned stack_size, //Stack size for new thread or 0.
 void *arglist //Argument list to be passed to new thread or NULL
);
uintptr_t _beginthreadex(
 void *security,//Pointer to a SECURITY_ATTRIBUTES structure
 unsigned stack_size,
 unsigned ( __stdcall *start_address )( void * ),
 void *arglist,
 unsigned initflag,//Initial state of new thread (0 for running or CREATE_SUSPENDED for suspended);
 unsigned *thrdaddr
);

  _beginthread函数与Win32 API 中的CreateThread函数类似,但有如下差异:

  (1)通过_beginthread函数我们可以利用其参数列表arglist将多个参数传递到线程;

  (2)_beginthread 函数初始化某些 C 运行时库变量,在线程中若需要使用 C 运行时库。

  3.终止线程

  线程的终止有如下四种方式:

  (1)线程函数返回;

  (2)线程自身调用ExitThread 函数即终止自己,其原型为:

VOID ExitThread(UINT fuExitCode );

  它将参数fuExitCode设置为线程的退出码。

  注意:如果使用C/C++编写代码,我们应该使用C/C++运行时库函数_endthread (_endthreadex)终止线程,决不能使用ExitThread!
_endthread 函数对于线程内的条件终止很有用。例如,专门用于通信处理的线程若无法获取对通信端口的控制,则会退出。

  (3)同一进程或其他进程的线程调用TerminateThread函数,其原型为:

BOOL TerminateThread(HANDLE hThread,DWORD dwExitCode);

  该函数用来结束由hThread参数指定的线程,并把dwExitCode设成该线程的退出码。当某个线程不再响应时,我们可以用其他线程调用该函数来终止这个不响应的线程。

  (4)包含线程的进程终止。

  最好使用第1种方式终止线程,第2~4种方式都不宜采用。

  4.挂起与恢复线程

  当我们创建线程的时候,如果给其传入CREATE_SUSPENDED标志,则该线程创建后被挂起,我们应使用ResumeThread恢复它:

DWORD ResumeThread(HANDLE hThread);

  如果ResumeThread函数运行成功,它将返回线程的前一个暂停计数,否则返回0x FFFFFFFF。

  对于没有被挂起的线程,程序员可以调用SuspendThread函数强行挂起之:

DWORD SuspendThread(HANDLE hThread);

  一个线程可以被挂起多次。线程可以自行暂停运行,但是不能自行恢复运行。如果一个线程被挂起n次,则该线程也必须被恢复n次才可能得以执行。
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章