幻谛

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

      多线程是一个程序内部实现多任务的能力。程序可以把自己分割为单独的执行“线程”。一个线程简单地被表示为可能调用程序中其他函数的函数。程序从其他主线程开始执行,这个主线程是在传统的C程序中叫做“main ”的函数,而在Windows中是WinMain。一旦运行起来程序可以通过在系统调用CreatThread中指定初始线程函数的名称来创建新的线程的执行。

      一个程序中的线程是同一进程的不同部分,因此他们共享进程的资源,如内存和打开的文件,因为线程共享的内存,所以他们还在共享静态变量。然而每个线程都有他们自己的堆栈,因此动态变量对每个线程是唯一的。每个线程还有他自己的处理器状态,这个状态在进行线程切换期间被保存和恢复。

创建新的执行线程的API函数是CreatThread。

---------------------------------------------------------------------------------------------------------------

它的语法如下:hThread = CreateThread(&security_attributes,dwStackSize,ThreadProc,pParam,dwFlags,&idThread);

第一个参数是指向SECURITY_ATTRIBUTES类型的结构的指针。
第二个参数用于新线程的初始堆栈大小。默认值为0。Windows根据需要动态延长堆栈的大小。
第三个参数是指向线程函数的指针。名称可以使任意的,但必须有如下语法:
DWORD WINAPI ThreadProc(PVOIO pParam)。
第四个参数为传递给ThreadProc的参数。这样主线程和次线程就可以共享数据。
第五个参数通常为0,但当创建的线程不马上执行时为标志CREATE_SUSPENDED。线程将刮起知道调用ResumeThread。
第六个参数是一个指针,指向接受线程ID的值的变量。
---------------------------------------------------------------------------------------------------
Win32 中CreateThread函数。

HANDLE CreateThread(lpsa,cbStack,lpStartAddr,lpvThreadParm,fdwCreate,lpIDThread)

LPSECURITY_ATTRIBUTES lpsa;  //address of thread security attrs。
     指向一个LPSECURITY_ATTRIBUTES结构,该结构为线程指定了安全属性。如果lpsa为NULL,则所创建的线程有一个缺省的安全描述符,且结构句柄不被继承。
DWORD cbStack;  // 初始新线程的堆栈大小。以字节为单位为新线程指定堆栈的大小。如果指定该参数为0,则堆栈大小缺省为和该进程的大小相同。该堆栈被自动化地在此进程的内存空间中分配,且当线程终止时,该堆栈被释放。如果需要的话,堆栈的大小会增长。
LPTHREAD_START_ROUTINE lpStartAddr;//线程函数的地址。指向将该线程执行的、应用程序提供的函数,并且代表该线程的起始地址。该函数接受一个单个的32位自变量,并返回一个32位退出码。
LPVOID lpvThreadParm;    //传递给线程的一个单个的32位参数。
DWORD fdwCreate; //Creation flags。指定控制线程的创建的附加标志。如果指定了CREATE_SUSPENDED标志,则该线程被创建在挂起状态,且知道调用ResumeThread函数才返回。如果该参数值为零,则该线程在创建后立即返回。
LPDWORD lpIDThread; //是一个指针,指向接受线程ID的值的变量。指向一个32位变量,它接受该线程的标识符。
   该函数创建一个线程以在调用进程的地址空间执行。如果函数成功,返回值为新线程的句柄;否则返回值为NULL。可通过调用GetLastError函数得到进一步的错误信息。


 

所创建的新线程的句柄具有对新线程的完全访问权限。如果未提供一个安全描述符,则该句柄可被用于任何要求一个线程对象句柄的函数中。当提供一个安全描述符时,在授予访问权限钱,在所有后继的对该句柄的使用中执行访问检查。如果此访问检查拒绝访问,则请求进程不可能使用该句柄来获得对此线程的访问。
      该线程的执行开始于lpStartAddr参数所指定的函数。如果该函数返回,则DWORD返回值被用来在对ExitThread函数的隐含调用中终止此线程。使用函数GetExitCodeThread可得到该线程的返回值。
      即使lpStartAddr参数指向数据、码,或者是不可访问的,CreateThread函数也有可能成功。如果线程运行时,起始地址无效,则发生一个异常,且线程终止。由于一个坏的起始地址而导致的线程终止将被作为一个对此线程的错误退出处理。这种行为类似于CreateProcess的异步属性,在CreateProcess中即使进程引用坏的或丢失的DLL,它也被创建。所创建的线程具有一个Thread_PRIORITY_NORMAL的线程优先级。使用GetThreadPrority和SetThreadPriority函数可获得和设置一个线程的优先级值。当一个线程终止时,线程对象获得一个有信号状态,以满足所有正等待该对象的进程。
      该线程对象一直驻留在系统中,知道此线程终止,且通过调用CloseHandle函数关闭了该线程的所有句柄为止。
      函数ExitProcess,ExitThread,CreateRemoteThread和一个正开始执行的进程(CreateProcess函数调用的结果)在一个进程里被相互串联起来。在某一时刻,这些事件中只能有一个在一个地址空间中发生。这意味着:
1:在进程初启和DLL初始化执行期间,可以创建新进程,但直到该进程的DLL初始化完成之后,才开始执行新线程。
2:在某一时刻,进程中只可以有一个线程在DLL初始化例程或分离例程中。
3:函数ExitProcess直到他们的DLL初始化例程或分离例程中没有线程时才返回。
posted on 2010-05-15 18:15  幻谛  阅读(374)  评论(0编辑  收藏  举报