浅谈线程

 

由于工作中经常跟线程打交道,所以就谈谈自己对线程的一些理解。说到线程就不得不先说进程,进程通常被定义为一个正在运行的程序的实例。进程是一个正在运行的程序,它拥有自己的虚拟地址空间,拥有自己的代码、数据和其他系统资源,如进程创建的文件、管道、同步对象等,一个进程也包含了一个或者多个运行在此进程内的线程。

那进程和程序又有什么区别了?虽然程序和进程在表面上很相似,但是它们有者根本的区别。程序是一连串静态的指令,而进程是一个容器,它包含了一系列运行在这个程序实例上下文中的线程使用的资源。

操作系统通过CreateProcess创建进程或,会创建一个线程执行进行中的的代码(也就是主线程),主线程可以创建其他线程,这些线程叫辅助线程也叫工作线程。

1.线程的创建

线程的创建是通过函数CreateThread来实现的,

 HANDLE CreateThread(

 LPSECURITY_ATTRIBUTES lpThreadAttributes,    //线程的安全属性

 DWORD dwStackSize,                        //线程堆栈的大小

 LPTHREAD_START_ROUTINE lpStartAddress,     //线程函数的起始地址

 LPVOID lpParameter,                        //传递个线程函数的参数

 DWORD dwCreationFlags,                    //线程创建后是否立即启动

 LPDWORD lpThreadId                        //线程的ID

);

每个线程都要都要有个入口函数(也就是线程函数),

下面是一个线程函数定义的例子:DWORD WINAPI ThreadProcLPVOID lpParam);

WINAPI是个宏 #define WINAPI _stdcall;

2.线程的内核对象

线程内核对象就是一个数据结构,包含了线程的一些信息。当成功调用CreateThread后,系统都会在内部为新线程分配一个内核对象。

内核对象的基本成员:

Context

Context也就是线程上下文,包括了一组CPU寄存器,反映了线程上次运行时CPU寄存器的状态。

Usage Count

Usage Count就是线程的使用计数。线程只要没有结束,Usage Count就至少为1。当这个值为0时,系统就认为已经没有任何进程在引用此内核对象了,于是线程内核对象就要从内存中撤销。在创建一个新的线程时,CreateThread函数返回内核对象的句柄,相当于打开一次新创建的内核对象,这会促使Usage Count1,所以创建一个新的线程后,Usage Count就是2。调用函数OpenThread会使Usage Count再次加1,而CloseHandle会使Usage Count1

Suspend Count

Suspend Count暂停次数。用ResumeThread函数可以唤醒一个线程,会减少Suspend Count,当Suspend Count0时线程被恢复运行。用SuspendThread函数挂起一个线程,这个函数会增加Suspend Count

Exit Code

Exit Code就是线程退出代码(也就是线程函数的返回值),当线程函数还没有执行完时,Exit Code的值就是STILL_ACTIVE

Signaled

Signaled指示线程对象是否为受信状态。线程运行时Signaled永远是False也就是未受信。只有线程结束后才是受信状态。

3.线程的优先级

首先得说下Windows调度线程的原则:只有优先级最高的线程是可调度的,操作系统就不会将CPU分配给优先级低的。但是有些方法会使线程暂停或者不可调度,如WaitForSingleObject或者GetMessage,这样优先级低的就可以分配到CPU的时间片,一旦优先级高的线程被唤醒了,优先级低的线程将被阻塞。Windows支持6个优先级类:idlebelow normalnormalabove normalhighreal-time

4.线程的终止

终止线程有4种方法:

1.       使用ExitThread函数终止线程

采用这种方法终止线程,会使系统释放掉此线程使用的所有资源但是c/c++资源却不能得到正确的清除。

2.       使用TerminateThread函数在一个线程中强制终止另一个线程的执行

使用TerminateThread函数终止线程,系统不会释放线程使用的堆栈,所以除非迫不得已,尽量避免使用这个函数终止线程。

3.       使用ExitProcess函数结束进程

使用这个方法相当与对进程中的每个线程使用TerminateThread函数。

4.       线程函数自然退出

这种方法是最好的,线程函数返回时Windows将终止线程的执行。

函数说明:

Handle OpenThread(

         DWORD dwDesiredAccess//想要访问的权限

         BOOL bInheritHandle,     //此函数返回的句柄是否可以被子进程继承

         DWORD deThreadId           //目标线程的ID

)

Void ExitThread(DWORD dwExitCode);//dwExitCode线程的退出代码

BOOL TerminateThread(HANDLE hThread,DWORD dwExitCode);//hThread目标线程句柄

posted @ 2009-02-28 13:37 十二号的国王 阅读(...) 评论(...) 编辑 收藏