多线程测试

本文描述了作者在使用控制台编写多线程程序时遇到的问题,线程执行顺序固定,怀疑可能由于CPU执行过快或代码中全局变量导致。作者分享了用于缓冲区操作的BufferThreadProc和EatThreadProc函数,以及对线程同步机制(如临界区和信号量)的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

因为我不想写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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值