Win32 多线程使用

本文详细介绍了WindowsAPI中的CreateThread、Mutex、Semaphore和Event函数,以及如何在生产者消费者模型中使用这些工具管理线程间的同步。通过Buffer结构和例子展示了如何创建和协调线程操作资源。

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

常用API

函数说明参数
CreateThread创建线程lpEventAttributes:安全属性,使用NULL采用默认安全属性
dwStackSize:线程堆栈大小,使用0表示采用默认大小
lpStartAddress:线程执行函数
lpParameter:给线程执行函数传入的参数
dwCreationFlags:新线程创建标志,0表示立即运行
lpThreadId:线程ID
GetCurrentThreadId获取当前线程ID
CreateMutex创建互斥量lpMutexAttributes:安全属性,使用NULL采用默认安全属性
bInitialOwner:互斥量初始状态,True表示调用线程拥有互斥量
lpName:互斥量名称,如果为NULL表示无名称(有名称可以跨进程使用)
ReleaseMutex释放互斥量
CreateSemaphore创建信号量lpSemaphoreAttributes:安全属性,使用NULL采用默认安全属性
lInitialCount:信号量初始数值
lMaximumCount:信号量最大数值
lpName:信号量名称,如果为NULL表示无名称(有名称可以跨进程使用)
ReleaseSemaphore增加信号量的计数hSemaphore:信号量句柄
lReleaseCount:信号量增加个数
lpPreviousCount:之前信号量值,使用NULL表示采用之前存储的
CreateEvent创建事件lpEventAttributes:安全属性,使用NULL采用默认安全属性
bManualReset:事件重置类型,TRUE为自动重置,FALSE为手动
bInitialState:初始状态,TRUE表示有状态
lpName:事件名称,如果为NULL表示无名称(有名称可以跨进程使用)
SetEvent将事件对象的状态设置为 signaled
ResetEvent将事件状态重置为非 signaled
WaitForSingleObject等待单个内核对象hHandle:Thread、Mutex、Semaphore、Event等
dwMilliseconds:等待超时时间,INFINITE表示无限等待
GetExitCodeThread获取线程退出码可以使用WaitForSingleObject等待线程退出,线程的返回值就是退出码
CloseHandle关闭句柄Thread、Mutex、Semaphore、Event使用完都应该关闭

Event、Mutex、Semaphore 区别

  • Event:用于线程之间的信号通知。一个线程可以通过将事件状态设置为 signaled 来通知其他等待该事件的线程
  • Mutex:用于实现临界区的互斥访问。只允许一个线程访问被互斥量保护的资源,其他线程必须等待。
  • Semaphore:用于控制对一组资源的访问。信号量维护一个计数器,多个线程可以同时访问被信号量保护的资源,但是计数器的值决定了能够同时访问资源的线程数量。

生产者消费者模型

#define BUFFER_SIZE 5

typedef struct Buffer {
	int data[BUFFER_SIZE];
	int size;
	int in;
	int out;
	HANDLE mutex;
	HANDLE full;
	HANDLE empty;
}Buffer;

static DWORD WINAPI ProducerThread(LPVOID lpParameter) {
	DWORD threadId = GetCurrentThreadId();
	printf("%d ProducerThread Running!\n", threadId);

	Buffer* buffer = (Buffer*)lpParameter;
	int index = 0;
	while (true) {
		WaitForSingleObject(buffer->empty, INFINITE);
		WaitForSingleObject(buffer->mutex, INFINITE);

		printf("write data = %d \n", index);
		buffer->data[buffer->in] = index++;
		buffer->in = (buffer->in + 1) % BUFFER_SIZE;

		ReleaseMutex(buffer->mutex);
		ReleaseSemaphore(buffer->full, 1, NULL);

		Sleep(2000);
	}

	return 0;
}

static DWORD WINAPI ConsumeThread(LPVOID lpParameter) {
	DWORD threadId = GetCurrentThreadId();
	printf("%d ConsumeThread Running!\n", threadId);

	Buffer* buffer = (Buffer*)lpParameter;
	while (true)
	{
		WaitForSingleObject(buffer->full, INFINITE);
		WaitForSingleObject(buffer->mutex, INFINITE);

		int data = buffer->data[buffer->out];
		buffer->out = (buffer->out + 1) % BUFFER_SIZE;
		printf("read data = %d \n", data);

		ReleaseMutex(buffer->mutex);
		ReleaseSemaphore(buffer->empty, 1, NULL);

		int randTime = rand() % 10000;
		Sleep(2500);
	}

	return 0;
}

static void createProducerConsumeModel() {
	Buffer* buffer = (Buffer*)malloc(sizeof(Buffer));
	buffer->size = 0;
	buffer->in = 0;
	buffer->out = 0;
	buffer->mutex = CreateMutex(NULL, false, NULL);
	buffer->full = CreateSemaphore(NULL, 0, BUFFER_SIZE, NULL);
	buffer->empty = CreateSemaphore(NULL, BUFFER_SIZE, BUFFER_SIZE, NULL);
	
	DWORD dwProducerThreadId;
	DWORD dwConsumeThreadId;
	HANDLE hProducerThread = CreateThread(
		NULL, 0, ProducerThread, buffer, 0, &dwProducerThreadId
	);
	HANDLE hConsumeThread = CreateThread(
		NULL, 0, ConsumeThread, buffer, 0, &dwConsumeThreadId
	);

	printf("Create ProducerThread = %d ConsumeThread = %d \n", dwProducerThreadId, dwConsumeThreadId);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值