因为我不想写gui所以用的控制台写的,不过可能写的有问题,因为后面的线程顺序不会改变,永远是线程1->2->3->4,也可能是我的cpu执行太快了,因为之前上课测试的两条线程不用临界体10000次全局变量数据会有误差,而我试了一下我的开了20条线程跑不用临界体也不会有误差
#define BUFFER_THREAD_NUMBERS 2
#define EAT_THREAD_NUMBERS 4
HANDLE g_hSemaphore1;
HANDLE g_hSemaphore2;
CRITICAL_SECTION g_cs1;
char temp = 0;
char strBuffer[0xff] = { 0 };
//我傻了调试了2个小时的bug,我以为什么情况呢,结果是最后打印的时候number填错了。。。
//缓冲区分割字符串最后一位,然后释放一次信号,等待信号返回,数据被单条线程获得后再离开临界体
//不知道为什么,是我的cpu太快了吗?,永远排序都是按照顺序排序,根本就没有感觉是按照20ms分配线程,
DWORD _stdcall BufferThreadProc(PVOID parameter) {
while (true) {
EnterCriticalSection(&g_cs1);
if (!strBuffer[0]) {
LeaveCriticalSection(&g_cs1);
break;
}
temp = strBuffer[strlen(strBuffer) - 1];
strBuffer[strlen(strBuffer) - 1] = 0;
printf("Buffer%d:%c\n", (DWORD)parameter, temp);
ReleaseSemaphore(g_hSemaphore1, 1, 0);
WaitForSingleObject(g_hSemaphore2, INFINITE);
LeaveCriticalSection(&g_cs1);
Sleep(500);
}
return 0;
}
//吃函数:主要做字符串处理,做完后再返回缓冲区的信号值
DWORD _stdcall EatThreadProc(PVOID parameter) {
char* buffer = (char*)parameter;
char buffer2[2] = { 0 };
while (true) {
WaitForSingleObject(g_hSemaphore1, INFINITE);
sprintf(buffer2, "-%c", temp);
strcat(buffer, buffer2);
ReleaseSemaphore(g_hSemaphore2, 1, 0);
}
return 0;
}
int main() {
char eatBuffer[EAT_THREAD_NUMBERS][0x40] = { 0 };
HANDLE threadBuffer[BUFFER_THREAD_NUMBERS];
InitializeCriticalSection(&g_cs1);
g_hSemaphore1 = CreateSemaphore(0, 0, 4, 0);
g_hSemaphore2 = CreateSemaphore(0, 0, 2, 0);
HANDLE threadEat[EAT_THREAD_NUMBERS];
for (size_t i = 0; i < EAT_THREAD_NUMBERS; i++) {
threadEat[i] = CreateThread(0, 0, EatThreadProc, (PVOID)eatBuffer[i], 0, 0);
if (!threadEat[i]) {
printf("Create thread failed\n");
return 0;
}
}
while (TRUE) {
printf("input:");
scanf("%s", strBuffer);
if (!strcmp(strBuffer,"stop")) {
break;
}
printf("\n");
//每次输入新的字符串的时候就重新创建线程一次,然后执行完后销毁
for (size_t i = 0; i < BUFFER_THREAD_NUMBERS; i++) {
threadBuffer[i] = CreateThread(0, 0, BufferThreadProc, (PVOID)i, 0, 0);
if (!threadBuffer[i]) {
printf("Create thread failed\n");
return 0;
}
}
WaitForMultipleObjects(BUFFER_THREAD_NUMBERS, threadBuffer, TRUE, INFINITE);
for (size_t i = 0; i < EAT_THREAD_NUMBERS; i++) {
printf("eat[%d]:%s\n", i, eatBuffer[i]);
}
for (size_t i = 0; i < BUFFER_THREAD_NUMBERS; i++) {
CloseHandle(threadBuffer[i]);
}
}
DeleteCriticalSection(&g_cs1);
for (size_t i = 0; i < EAT_THREAD_NUMBERS; i++) {
CloseHandle(threadEat[i]);
}
return 0;
}