|
阅读:597回复:0
多线程编程
Win32函数库里提供了多线程控制的操作函数,包括创建线程、终止线程、建立互斥区等。首先,在应用程序的主线程或者其它活动线程的适当的地方创建新的线程,创建线程的函数如下:
HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ); 参数lpThreadAttributes 指定了线程的安全属性,在Windows 95中被忽略; 参数dwStackSize 指定了线程的堆栈深度; 参数lpStartAddress 指定了线程的起始地址,一般情况为下面原型的函数 DWORD WINAPI ThreadFunc( LPVOID ); 参数 lpParameter指定了线程执行时传送给线程的32位参数,即上面函数的参数; 参数dwCreationFlags指定了线程创建的特性; 参数 lpThreadId 指向一个DWORD变量,可返回线程ID值。 如果创建成功则返回线程的句柄,否则返回NULL。 创建了新的线程后,线程开始启动执行,如果在dwCreationFlags中用了CREATE_SUSPENDED特性,那么线程并不马上执行,而是先挂起,等到调用ResumeThread后才开始启动线程,在这过程中可以调用函数 BOOL SetThreadPriority( HANDLE hThread, int nPriority); 设置线程的优先权。 当线程的函数返回后,线程自动终止,如果要想在线程的执行过程中终止的话,可以调用函数 VOID ExitThread( DWORD dwExitCode); 如果在线程的外面终止线程的话,可以用下面的函数 BOOL TerminateThread( HANDLE hThread, DWORD dwExitCode ); 但注意,该函数可能会引起系统不稳定,而且,线程所占用的资源也不释放,因此,一般情况下,建议不要使用该函数。 如果要终止的线程是进程内的最后一个线程的话,在线程被终止后,相应的进程也终止。 2.2 用Win32函数控制线程对共享资源的访问 在线程体内,如果该线程完全独立,与其它的线程没有数据存取等资源操作上的冲突的话,可以按照通常单线程的方法进行编程,但在多线程处理时,情况常常不是这样,线程之间经常要同时去访问一些资源,例如,一个线程负责公式计算,另一个线程负责结果的显示,两个线程都要访问同一个结果变量。这时如果不进行冲突控制的话,很有可能会显示不正确的结果。 对共享资源进行访问引起冲突是不可避免的,但我们可以用以下的办法进行操作控制: (1) 通过设置线程的互斥体对象,在可能冲突的地方进行同步控制; 先建立互斥体对象,得到句柄; HANDLE CreateMutex( ); 然后在线程可能冲突区域的开始,即访问共享资源之前,调用WaitForSingleObject,把句柄传给函数,请求占用互斥体对象 dwWaitResult = WaitForSingleObject(hMutex, 5000L); 共享资源访问完后,释放对互斥体对象的占用 ReleaseMutex(hMutex); 互斥体对象在同一时刻只能被一个线程占用,在一个线程占用时,若有另一线程想占用的话,必须等前一线程释放才能成功。 (2) 设置信号,在操作共享资源前,打开信号,完成操作后,关闭信号; 类似于互斥体对象的处理,首先创建信号对象 HANDLE CreateSemaphore( ); 或者打开一个信号对象 HANDLE OpenSemaphore( ); 然后在线程的访问共享资源之前,调用WaitForSingleObject, 共享资源访问完后,释放对信号对象的占用 ReleaseSemaphore(); |
|
|