线程的初始化到运行过程

    以前一直对线程的创建、运行过程不清楚,现在看了Windows核心编程的讲解之后总算是比较清楚了,现在就将我看的知识点总结一下。先介绍一下线程的创建函数CreateThread,函数原型如下(摘至MSDN的说明,加上了一些简单的字面翻译):

HANDLE CreateThread (
  SEC_ATTRS
SecurityAttributes,
  ULONGStackSize,
  SEC_THREAD_STARTStartFunction,
  PVOIDThreadParameter,
  ULONGCreationFlags,
  PULONGThreadId
);

Parameters
SecurityAttributes
[in] Pointer to a SEC_ATTRS structure that determines whether the returned handle can be inherited by child processes.
指向一个SEC_ATTRS 结构的指针用来指明线程返回的句柄是否能被线程所属进程的子进程继承。
StackSize
[in] Specifies the initial commit size of the stack, in bytes.
指定线程初始化的栈的字节数
StartFunction
[in] Pointer to the application-defined function of type SEC_THREAD_START to be executed by the thread. 指向一个SEC_THREAD_START类型的应用程序定义函数的指针,这个函数会被线程执行。
ThreadParameter
[in] Pointer to a single parameter value passed to the thread.
指向一个传递给线程的单个参数值的指针
CreationFlags
[in] Specifies flags that control the creation of the thread.
指定线程创建过程中的控制标志,可以控制线程创建后马上挂起
ThreadId
[out] Pointer to a variable that receives the thread identifier.
指向一个返回线程定义值的指针,即线程ID
Return Values

If the function succeeds, the return value is a handle to the new thread.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.image_thumb[3]

    在调用CreateThead创建线程的时候,操作系统会为新线程创建线程内核对想象,如图所示,线程内核对象包含了线程的上下文(是一个C O N T E X T结构)以及一些其他属性和统计信息,注意线程是在上下文中运行的,上下文包含了堆栈指针寄存器SP,指令指针寄存器IP,和一些其他的CPU寄存器。在线程创建的时候,系统会把CreateThread传递进来的线程运行函数和参数一次压栈,同时会把一个为称为BaseThreadStart的未文档化(和未输出)的函数的地址放入IP寄存器中,当线程初始化完成并处于可以运行状态时,BaseThreadStart函数就会被执行,如下 :

image

    下面一段摘自windows核心编程的说明:

当新线程执行BaseThreadStart函数时,将会出现下列情况:
• 在线程函数中建立一个结构化异常处理(S E H)帧,这样,在线程执行时产生的任何异常情
况都会得到系统的某种默认处理(关于结构化异常处理的详细说明参见第2 3、2 4和2 5章)。
• 系统调用线程函数,并将你传递给CreateThead函数的pvParam参数传递给它。
• 当线程函数返回时, BaseThreadStart调用ExitThread,并将线程函数的返回值传递给它。
该线程内核对象的使用计数被递减,线程停止执行。
• 如果线程产生一个没有处理的异常条件,由BaseThreadStart函数建立的S E H帧将负责处理
该异常条件。通常情况下,这意味着向用户显示一个消息框,并且在用户撤消该消息框时,
BaseThreadStart调用ExitThread,以终止整个进程的运行,而不只是终止线程的运行。

    这一节主要说明了线程运行函数具体是怎样被执行的。下面一节将介绍为什么要用C/C++运行库的_beginthreadex而不要用CreateThead直接创建线程?为什么说用CreateThead可能会导致线程内存泄露?

posted @ 2010-11-12 12:15  小马喝水  阅读(876)  评论(0编辑  收藏  举报