要求: 有四個線程,線程1只輸出A,線程2只輸出B,如此類推。現需要讓這四個線程按順序輸出ABCDABCD........
1.首先我們可以先定義線程運行函數,只要不斷輸出所需要的字母就可以了。
1 int count = 0; 2 DWORD WINAPI function(LPVOID pm) 3 { 4 int tmp = (int)pm; 5 char c = 'A' + tmp; 6 while (true) 7 { 8 if (count >= 100) 9 { 10 break; 11 } 12 printf("%d curThread:%c count = %d\n", tmp, c, count); 13 count++; 14 } 15 return 0; 16 }
2.然后在main函數創建4個線程,並啟動,就會不斷輸出字母。
int main() { for (int i = 0; i < 4; i++) { hl[i] = CreateThread(NULL, 0, function, (void *)i, 0, NULL); } Sleep(10000); return 0; }
但是如何做到按順序呢,這就需要掛起線程,並讓下一個線程運行。當下一個線程運行完一次循環,再掛起,讓第三個線程運行,如此循環下去。
可以使用 WaitForSingleObject 來掛起線程,並設置時限為INFINITE,直到所等待線程接收到信號才繼續執行。
可以使用SetEvent來給線程標志信號,和WaitForSingleObject配合使用。
同時,需要一些輔助的Event來讓輸出字符的線程等待。
(如果不使用輔助的Event,比如直接讓線程A等待線程D,線程B等待線程A,線程C等待線程B,線程D等待線程C,這樣會造成一個死循環,會死鎖。
如果直接自己等待自己,然后用SetEvent來讓下一個線程跑起來,邏輯上是沒錯的,但是在線程創建階段,需要等待的線程都可能沒創建起來就開始等待了,結果是線程等待着一個空的HANDLE沒法再起來了。)
具體看代碼吧:
#include <stdio.h> #include <Windows.h> char s[100]; int count; HANDLE handler[4]; HANDLE hl[4]; DWORD WINAPI function(LPVOID pm) { int tmp = (int)pm; char c = 'A' + tmp; while (true) { WaitForSingleObject(handler[tmp], INFINITE); if (count >= 100) { break; } printf("%d curThread:%c count = %d\n", tmp, c, count); s[count] = (char)pm; count++; Sleep(100); SetEvent(handler[(tmp+1)%4]); } return 0; } int main() { for (int i = 0; i < 4; i++) { handler[i] = CreateEvent(NULL, false, false, NULL); hl[i] = CreateThread(NULL, 0, function, (void *)i, 0, NULL); } printf("start\n"); SetEvent(handler[0]); WaitForMultipleObjects(4, handler, true, INFINITE); printf("done!\n"); return 0; }
