当前位置:文档之家› Windows多线程程序设计

Windows多线程程序设计

Windows多线程程序设计- -1、产生一个线程,只是个框架,没有具体实现。

理解::CreateThread函数用法。

#includeDWORD WINAPI ThreadFunc(LPVOID);int main(){HANDLE hThread;DWORD dwThreadID;hThread = ::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(ThreadFunc),NULL,0,&dwThreadID);...;return 0;}DWORD WINAPI ThreadFunc(LPVOID lParam){...;return 0;}2、一个真正运转的多线程程序,当你运行它的时候,你会发现(也可能会害怕),自己试试吧。

说明了多线程程序是无法预测其行为的,每次运行都会有不同的结果。

#include#includeusing namespace std;DWORD WINAPI ThreadFunc(LPVOID);int main(){HANDLE hThread;DWORD dwThreadID;// 产生5个线程for(int i=0; i<5; i++){hThread = ::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(ThreadFunc),(LPVOID)&i,0,&dwThreadID);if(dwThreadID)cout << "Thread launched: " << i << endl;}// 必须等待线程结束,以后我们用更好的处理方法Sleep(5000);return 0;}DWORD WINAPI ThreadFunc(LPVOID lParam){int n = (int)lParam;for(int i=0; i<3; i++){cout << n <<","<< n <<","<< n << ","< }return 0;}3、使用CloseHandle函数来结束线程,应该是“来结束核心对象的”,详细要参见windows 多线程程序设计一书。

修改上面的程序,我们只简单的修改if语句。

if(dwThreadID){cout << "Thread launched: " << i << endl;CloseHandle(dwThreadID);}4、GetExitCodeThread函数的用法和用途,它传回的是线程函数的返回值,所以不能用GetExitCodeThread的返回值来判断线程是否结束。

#include#includeusing namespace std;DWORD WINAPI ThreadFunc(LPVOID);int main(){HANDLE hThread1;HANDLE hThread2;DWORD dwThreadID1;DWORD dwThreadID2;DWORD dwExitCode1 = 0;DWORD dwExitCode2 = 0;hThread1 = ::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(ThreadFunc),(LPVOID)1,0,&dwThreadID1);if(dwThreadID1)cout << "Thread launched: " << dwThreadID1 << endl;hThread2 = ::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(ThreadFunc),(LPVOID)2,0,&dwThreadID2);if(dwThreadID2)cout << "Thread launched: " << dwThreadID2 << endl;while(1){cout<<"Press any key.";cin.get();GetExitCodeThread(hThread1, &dwExitCode1);GetExitCodeThread(hThread2, &dwExitCode2);if( dwExitCode1 == STILL_ACTIVE )cout< if( dwExitCode2 == STILL_ACTIVE )cout< if( dwExitCode1 != STILL_ACTIVE && dwExitCode2 != STILL_ACTIVE ) break;}CloseHandle(hThread1);CloseHandle(hThread2);cout<<"thread 1 returned: "< cout<<"thread 2 returned: "< return 0;}DWORD WINAPI ThreadFunc(LPVOID lParam){DWORD n = (DWORD)lParam;Sleep(n*2000);return n*10;}所以,最终判断线程是否结束还是运行,运用下面的方法,这段代码很重要哦,但它始终是个busy loop,还不是最好的方法。

while(1){BOOL rc;rc = GetExitCodeThread(hThread, dwThreadID);if(rc && dwThreadId != STILL_ACTIVE)break;}5、上面我们已经提到了等待一个线程结束的问题,这里我们讲继续讲述最好的方法。

使用WaitForSingleObject(HANDLE, DWORD);同时上面的busy loop我们可以用这个函数代理了,WaitForSingleObject(hThread, INFINISH); 看代码吧。

#include#includeusing namespace std;const int NUM_TASKS = 6;const int THREAD_POOL_SIZE = 3;const int MAX_THREAD_INDEX = 2;DWORD WINAPI ThreadFunc(LPVOID);int main(){HANDLE hThread[THREAD_POOL_SIZE];int slot = 0;DWORD dwThreadID;DWORD dwExitCode = 0;for(int i=1; i {if(i>THREAD_POOL_SIZE){WaitForSingleObject(hThread[slot], INFINITE);GetExitCodeThread(hThread[slot], &dwExitCode);cout<<"Slot "< CloseHandle(hThread[slot]);}hThread[slot] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc,(LPVOID)slot,0,&dwThreadID);cout<<"launched thread "< if(++slot>MAX_THREAD_INDEX)slot=0;}for(slot=0; slot {WaitForSingleObject(hThread[slot], INFINITE);CloseHandle(hThread[slot]);}cout<<"all thread terminated."< return 0;}DWORD WINAPI ThreadFunc(LPVOID lParam){srand(GetTickCount());Sleep((rand()%8)*500+500);cout<<"slot "<<(DWORD)lParam<<" idle."< return (DWORD)lParam;}我们发现,调用WaitForSingleObject()并放置一个“线程核心对象”作为参数,将是调用线程#1开始睡眠,直到线程#2(我们刚刚说的线程核心对象)结束为止。

就想Sleep()函数一样。

INFINITE代表无穷等待,呵呵。

6、使用WaitForMultipleObject(DWORD nCount, CONST HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliSeconds)解释一下参数:nCount指的是lpHandles数组元素的个数。

lpHandles指的是核心对象数组。

bWaitAll一般为TRUE。

dwMilliSeconds一般为INFINITE。

7、下面我们要接触到的是同步问题了,如果你不知道同步是什么,最好上网搜索一下。

简单的一个含有Critical_Section的链表的代码:typedef struct _Node{struct _Node* next;int data;}Node;typedef struct _List{Node* head;Node* tail;CRITICAL_SECTION critical_sec;}List;List* CreateList(){List *pList = new List;pList->head = NULL;pList->tail = NULL;InitializeCriticalSection(&pList->critical_sec);return pList;}DeleteCriticalSection(&pList->critical_sec);do{Node* node;node = pList->head;delete node;}while(pList->head = pList->head->next != NULL)void AddHead(List* pList, Node* newNode){EnterCriticalSection(&pList->critical_sec);newNode->next = pList->head;pList->head = newNode;LeaveCriticalSection(&pList->critical_sec);}void AddTail(List* pList, Node* newNode){EnterCriticalSection(&pList->critical_sec);pList->tail->next = newNode;newNode->next = NULL;pList->tail = newNode;LeaveCriticalSection(&pList->critical_sec);}Node* Next(List* pList, Node* node){Node* Next;EnterCriticalSection(&pList->critical_sec);Next = node->next;LeaveCriticalSection(&pList->critical_sec);return next;}不知道有没有问题,自己没有测试,如果你有心就测试一下吧。

相关主题