Windows C++ 原生线程池同步控制与文件IO操作指南

Felix
Felix
发布时间:2026-10-16| 4人浏览过
原创

基于Windows API构建的C++线程池通过任务队列与工作线程分离,实现高并发请求处理。文章重点讲解CreateThreadpoolWork结合互斥锁、信号量、内核事件和临界区的同步用法,并展示异步文件读写、大小获取及指针控制的标准流程。

一、 线程池核心概念与场景

线程池主要由两部分构成:负责存放主线程提交任务的“任务队列”,以及循环从队列中提取并执行任务的“工作线程队列”。这种模型类似于一个生产者(主线程)和多个消费者(工作线程)的结构。在高并发的网络服务端开发中,通常采用“One Loop Per Thread + Thread Pool”模式,由专用线程接收请求并解析,将实际的数据计算任务分发至计算线程池,从而提升资源利用率。

二、 C++原生线程池同步策略

在使用 CreateThreadpoolWork 创建工作单元时,回调函数支持多种系统级同步对象。以下分别演示四种常见的同步方式及其操作入口。

第1步:使用互斥量 (Mutex) 进行同步

目的:确保同一时刻只有一个线程访问共享资源。
入口:调用 CreateMutex 创建对象,传入回调函数。
动作:在线程开始前使用 WaitForSingleObject 锁定,结束后使用 ReleaseMutexWhenCallbackReturns 解锁。

void NTAPI TaskHandlerMutex(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WORK Work)
{
	// 锁定资源
	WaitForSingleObject(*(HANDLE *)Context, INFINITE);
	for (int x = 0; x < 100; x++)
	{
		printf("线程ID: %d ---> 子线程: %d \n", GetCurrentThreadId(), x);
	}
	// 解锁资源
	ReleaseMutexWhenCallbackReturns(Instance, *(HANDLE*)Context);
}

void TestMutex()
{
	HANDLE hMutex = CreateMutex(NULL, FALSE, NULL);
	PTP_WORK pool = CreateThreadpoolWork((PTP_WORK_CALLBACK)TaskHandlerMutex, &hMutex, NULL);
	for (int i = 0; i < 1000; i++) SubmitThreadpoolWork(pool);
	WaitForThreadpoolWorkCallbacks(pool, FALSE);
	CloseHandle(hMutex);
}

第2步:使用内核事件 (Kernel Event) 进行同步

目的:通过信号通知机制控制线程执行。
入口:调用 CreateEvent 创建对象。
动作:等待信号后执行任务,完成后调用 SetEventWhenCallbackReturns 触发信号。

void NTAPI TaskHandlerKern(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WORK Work)
{
	WaitForSingleObject(*(HANDLE *)Context, INFINITE); // 等待事件被置为有信号状态
	// ... 执行任务 ...
	SetEventWhenCallbackReturns(Instance, *(HANDLE*)Context); // 结束前触发事件
}

void TestKern()
{
	HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	SetEvent(hEvent); // 预设为有信号状态
	PTP_WORK pwk = CreateThreadpoolWork((PTP_WORK_CALLBACK)TaskHandlerKern, &hEvent, NULL);
	for (int i = 0; i < 1000; i++) SubmitThreadpoolWork(pwk);
	WaitForThreadpoolWorkCallbacks(pwk, FALSE);
	CloseHandle(hEvent);
}

第3步:使用信号量 (Semaphore) 进行同步

目的:限制同时执行任务的线程数量或计数。
入口:调用 CreateSemaphore,注意初始值与最大值的设置。
动作:使用 WaitForSingleObject 等待配额,使用 ReleaseSemaphoreWhenCallbackReturns 归还配额。

void NTAPI TaskHandlerSemaphore(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WORK Work)
{
	WaitForSingleObject(*(HANDLE *)Context, INFINITE);
	// ... 执行任务 ...
	ReleaseSemaphoreWhenCallbackReturns(Instance, *(HANDLE*)Context, 1); // 释放1个计数
}

void TestSemaphore()
{
	HANDLE hSemaphore = CreateSemaphore(NULL, 0, 100, NULL);
	ReleaseSemaphore(hSemaphore, 10, NULL); // 预先增加10个可用数
	PTP_WORK pwk = CreateThreadpoolWork((PTP_WORK_CALLBACK)TaskHandlerSemaphore, &hSemaphore, NULL);
	for (int i = 0; i < 1000; i++) SubmitThreadpoolWork(pwk);
	WaitForThreadpoolWorkCallbacks(pwk, FALSE);
	CloseHandle(hSemaphore);
}

第4步:使用临界区 (Critical Section) 进行同步

目的:轻量级的用户态代码段保护。
入口:初始化 CRITICAL_SECTION。
动作:进入时使用 EnterCriticalSection,离开时使用 LeaveCriticalSectionWhenCallbackReturns。

void NTAPI TaskHandlerLeave(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WORK Work)
{
	EnterCriticalSection((CRITICAL_SECTION*)Context);
	// ... 执行任务 ...
	LeaveCriticalSectionWhenCallbackReturns(Instance, (CRITICAL_SECTION*)Context);
}

void TestLeave()
{
	CRITICAL_SECTION cs;
	InitializeCriticalSection(&cs);
	PTP_WORK pwk = CreateThreadpoolWork((PTP_WORK_CALLBACK)TaskHandlerLeave, &cs, NULL);
	for (int i = 0; i < 1000; i++) SubmitThreadpoolWork(pwk);
	WaitForThreadpoolWorkCallbacks(pwk, FALSE);
	DeleteCriticalSection(&cs);
}

三、 Windows 基础文件 IO 操作

C++ 可以使用 CreateFile 等 Win32 API 直接处理文件的写入、读取及属性管理。以下演示异步模式的典型用法。

第1步:异步文本读写流程

参数:GENERIC_WRITE 用于写,GENERIC_READ 用于读;FILE_FLAG_SEQUENTIAL_SCAN 优化顺序访问。
动作:先创建句柄,使用 WriteFile 写入数据并 FlushFileBuffers 刷新缓冲区,随后关闭写句柄再打开读句柄进行读取。

int ReadWriteIO()
{
	char enContent[] = "hello lyshark";
	char deContent[255] = { 0 };
	HANDLE hFileWrite = CreateFile(L"d://test.txt", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
	if (INVALID_HANDLE_VALUE == hFileWrite) return 0;
	WriteFile(hFileWrite, enContent, strlen(enContent), NULL, NULL);
	FlushFileBuffers(hFileWrite);
	CancelSynchronousIo(hFileWrite); // 可选:取消同步IO操作
	CloseHandle(hFileWrite);

	HANDLE hFileRead = CreateFile(L"d://test.txt", GENERIC_READ, 0, NULL, OPEN_ALWAYS, NULL, NULL);
	ReadFile(hFileRead, deContent, 255, NULL, NULL);
	std::cout << "读出内容: " << deContent << std::endl;
	CloseHandle(hFileRead);
	return 1;
}

第2步:获取文件大小

工具:GetFileSizeEx 获取大文件尺寸,返回值为 LARGE_INTEGER 结构。
操作:打开文件后调用 API,将结果打印输出。

int GetFileSize()
{
	HANDLE hFile = CreateFile(L"d://test.txt", 0, 0, NULL, OPEN_EXISTING, NULL, NULL);
	ULARGE_INTEGER ulFileSize;
	GetFileSize(hFile, &ulFileSize.HighPart);
	LARGE_INTEGER lFileSize;
	GetFileSizeEx(hFile, &lFileSize);
	std::cout << "文件大小A: " << ulFileSize.QuadPart << " bytes" << std::endl;
	CloseHandle(hFile);
	return 1;
}

第3步:移动文件指针与设置

入口:使用 LARGE_INTEGER 指定偏移量。
动作:调用 SetFilePointerEx 设置绝对位置(如从文件头开始),或使用 SetEndOfFile 截断/扩展文件末尾,最后读取指定区域。

int SetFilePointer()
{
	DWORD readCount = 0;
	char deContent[255] = { 0 };
	HANDLE hFile = CreateFile(L"d://test.txt", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, NULL, NULL);
	LARGE_INTEGER liMove;
	liMove.QuadPart = 2; // 从第2字节开始
	SetFilePointerEx(hFile, liMove, NULL, FILE_BEGIN);
	SetEndOfFile(hFile);
	ReadFile(hFile, deContent, 255, &readCount, NULL);
	std::cout << "移动指针后读取: " << deContent << " 长度: " << readCount << std::endl;
	CloseHandle(hFile);
	return 0;
}
以上就是C++原生API实现线程池同步及文件IO操作的详细内容,更多关于Windows多线程与文件编程的资料请关注本站其它相关文章!
相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。