要实现三个线程按顺序输出 "A", "B", "C" 并循环10次的任务,关键在于线程间的同步与协调。解决思路可以分为以下几个步骤:
1. 定义互斥量和条件变量
- 互斥量:用来保证对共享资源(如标志变量)的访问是互斥的,即同一时刻只有一个线程可以访问。
- 条件变量:用来让线程等待特定条件,并在条件满足时被唤醒。
2. 定义标志变量
- 标志变量:用来指示当前应该运行哪个线程。初始值为0,表示线程A先运行;1表示线程B运行;2表示线程C运行。
3. 线程函数
- 每个线程函数根据标志变量判断是否可以执行,如果不能执行则等待对应的条件变量。
- 输出对应的字符后,更新标志变量,并触发下一个线程的条件变量。
4. 主函数
- 初始化互斥量和条件变量。
- 创建三个线程,并让它们分别执行对应的函数。
等待所有线程结束,最后销毁互斥量和条件变量。-
#include <stdio.h> #include <windows.h> #define NUM_CYCLES 10 HANDLE mutex; // 互斥量,用于线程同步 HANDLE condA, condB, condC; // 事件变量,用于线程间的条件同步 int flag = 0; // 标志变量,0表示线程A运行,1表示线程B运行,2表示线程C运行 // 线程A的函数 DWORD WINAPI printA(LPVOID param) { for (int i = 0; i < NUM_CYCLES; ++i) { WaitForSingleObject(mutex, INFINITE); // 获取互斥量锁 while (flag != 0) { WaitForSingleObject(condA, INFINITE); // 等待condA事件 } printf("A"); // 输出A fflush(stdout); // 确保立即输出 flag = 1; // 设置标志为1,表示下一个运行的是线程B SetEvent(condB); // 触发condB事件,唤醒线程B ReleaseMutex(mutex); // 释放互斥量锁 } return 0; } // 线程B的函数 DWORD WINAPI printB(LPVOID param) { for (int i = 0; i < NUM_CYCLES; ++i) { WaitForSingleObject(mutex, INFINITE); // 获取互斥量锁 while (flag != 1) { WaitForSingleObject(condB, INFINITE); // 等待condB事件 } printf("B"); // 输出B fflush(stdout); // 确保立即输出 flag = 2; // 设置标志为2,表示下一个运行的是线程C SetEvent(condC); // 触发condC事件,唤醒线程C ReleaseMutex(mutex); // 释放互斥量锁 } return 0; } // 线程C的函数 DWORD WINAPI printC(LPVOID param) { for (int i = 0; i < NUM_CYCLES; ++i) { WaitForSingleObject(mutex, INFINITE); // 获取互斥量锁 while (flag != 2) { WaitForSingleObject(condC, INFINITE); // 等待condC事件 } printf("C\n"); // 输出C并换行 fflush(stdout); // 确保立即输出 flag = 0; // 设置标志为0,表示下一个运行的是线程A SetEvent(condA); // 触发condA事件,唤醒线程A ReleaseMutex(mutex); // 释放互斥量锁 } return 0; } int main() { HANDLE threadA, threadB, threadC; // 线程句柄 // 初始化互斥量和事件 mutex = CreateMutex(NULL, FALSE, NULL); condA = CreateEvent(NULL, FALSE, FALSE, NULL); condB = CreateEvent(NULL, FALSE, FALSE, NULL); condC = CreateEvent(NULL, FALSE, FALSE, NULL); // 创建线程 threadA = CreateThread(NULL, 0, printA, NULL, 0, NULL); threadB = CreateThread(NULL, 0, printB, NULL, 0, NULL); threadC = CreateThread(NULL, 0, printC, NULL, 0, NULL); // 等待所有线程结束 WaitForSingleObject(threadA, INFINITE); WaitForSingleObject(threadB, INFINITE); WaitForSingleObject(threadC, INFINITE); // 关闭线程句柄 CloseHandle(threadA); CloseHandle(threadB); CloseHandle(threadC); // 销毁互斥量和事件 CloseHandle(mutex); CloseHandle(condA); CloseHandle(condB); CloseHandle(condC); return 0; }