要求: 有四个线程,线程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; }