html 手机网站开发,网站建设用哪个好,wordpress战队模板,福永三合一网站设计引言 在现代应用程序中#xff0c;多线程编程是实现高性能和高并发任务的关键手段。Windows 操作系统为开发者提供了一套强大的 API#xff0c;用于创建和管理线程、同步任务#xff0c;并优化线程性能。本文将深入探讨 C 中 Windows API 的多线程支持#xff0c;详细介绍线…引言 在现代应用程序中多线程编程是实现高性能和高并发任务的关键手段。Windows 操作系统为开发者提供了一套强大的 API用于创建和管理线程、同步任务并优化线程性能。本文将深入探讨 C 中 Windows API 的多线程支持详细介绍线程的创建与控制、线程优先级的设置、线程局部存储TLS、各种同步机制如临界区、互斥体、信号量、事件以及纤程Fibers的应用。
1. 线程的创建和控制
1.1 创建线程CreateThread
CreateThread 是 Windows API 用于创建线程的函数。它允许程序在不同的并发路径上运行代码从而提升应用程序的响应速度和处理能力。
示例创建一个简单的线程
#include windows.h
#include iostreamDWORD WINAPI ThreadFunc(LPVOID lpParam) {std::cout Thread is running. std::endl;return 0;
}int main() {HANDLE hThread CreateThread(nullptr, // 默认安全属性0, // 默认堆栈大小ThreadFunc, // 线程函数nullptr, // 线程函数参数0, // 默认创建标志nullptr // 不返回线程标识符);if (hThread) {WaitForSingleObject(hThread, INFINITE); // 等待线程完成CloseHandle(hThread); // 关闭线程句柄}return 0;
}1.2 线程退出与终止ExitThread 和 TerminateThread
ExitThread用于安全地退出线程。TerminateThread强制终止线程但会导致资源泄漏不推荐使用。
示例使用 ExitThread 安全退出线程
#include windows.h
#include iostreamDWORD WINAPI ThreadFunc(LPVOID lpParam) {std::cout Thread is running. std::endl;ExitThread(0); // 安全退出线程
}int main() {HANDLE hThread CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);if (hThread) {WaitForSingleObject(hThread, INFINITE); // 等待线程完成CloseHandle(hThread); // 关闭线程句柄}return 0;
}示例使用 TerminateThread 强制终止线程不推荐
#include windows.h
#include iostreamDWORD WINAPI ThreadFunc(LPVOID lpParam) {while (true) {std::cout Thread is running. std::endl;Sleep(1000);}return 0;
}int main() {HANDLE hThread CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);if (hThread) {Sleep(3000); // 让线程运行一段时间TerminateThread(hThread, 0); // 强制终止线程不推荐CloseHandle(hThread); // 关闭线程句柄}return 0;
}1.3 等待线程完成WaitForSingleObject 和 WaitForMultipleObjects
WaitForSingleObject用于等待单个线程或同步对象的信号。WaitForMultipleObjects用于等待多个线程或同步对象的信号。
示例使用 WaitForSingleObject 等待单个线程
#include windows.h
#include iostreamDWORD WINAPI ThreadFunc(LPVOID lpParam) {Sleep(2000); // 模拟长时间运行的操作std::cout Thread completed. std::endl;return 0;
}int main() {HANDLE hThread CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);if (hThread) {std::cout Waiting for thread to complete... std::endl;WaitForSingleObject(hThread, INFINITE); // 等待线程完成std::cout Thread has completed. std::endl;CloseHandle(hThread); // 关闭线程句柄}return 0;
}示例使用 WaitForMultipleObjects 等待多个线程
#include windows.h
#include iostreamDWORD WINAPI ThreadFunc(LPVOID lpParam) {Sleep(1000); // 模拟操作std::cout Thread *(int*)lpParam completed. std::endl;return 0;
}int main() {HANDLE hThreads[2];int threadParams[2] { 1, 2 };for (int i 0; i 2; i) {hThreads[i] CreateThread(nullptr, 0, ThreadFunc, threadParams[i], 0, nullptr);}std::cout Waiting for threads to complete... std::endl;WaitForMultipleObjects(2, hThreads, TRUE, INFINITE); // 等待所有线程完成for (int i 0; i 2; i) {CloseHandle(hThreads[i]); // 关闭线程句柄}std::cout All threads have completed. std::endl;return 0;
}2. 线程优先级
Windows 提供了丰富的 API 来控制线程的优先级以便更好地管理线程的执行顺序。
2.1 设置线程优先级SetThreadPriority
SetThreadPriority 允许开发者根据线程的重要性来调整其优先级从而影响调度器对线程的调度频率。
示例设置线程的优先级
#include windows.h
#include iostreamDWORD WINAPI ThreadFunc(LPVOID lpParam) {std::cout Thread is running at priority: GetThreadPriority(GetCurrentThread()) std::endl;return 0;
}int main() {HANDLE hThread CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);if (hThread) {SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST); // 设置线程优先级WaitForSingleObject(hThread, INFINITE);CloseHandle(hThread);}return 0;
}2.2 获取线程优先级GetThreadPriority
GetThreadPriority 用于获取当前线程的优先级以便对线程的执行情况进行监控或调整。
示例获取线程优先级
#include windows.h
#include iostreamDWORD WINAPI ThreadFunc(LPVOID lpParam) {std::cout Thread is running at priority: GetThreadPriority(GetCurrentThread()) std::endl;return 0;
}int main() {HANDLE hThread CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);if (hThread) {int priority GetThreadPriority(hThread);std::cout Initial thread priority: priority std::endl;SetThreadPriority(hThread, THREAD_PRIORITY_LOWEST); // 改变线程优先级priority GetThreadPriority(hThread);std::cout Changed thread priority: priority std::endl;WaitForSingleObject(hThread, INFINITE);CloseHandle(hThread);}return 0;
}3. 线程局部存储TLS
线程局部存储TLS允许线程在其本地范围内存储和访问数据。每个线程都有独立的存储区域不会与其他线程共享。
3.1 分配 TLS 索引TlsAlloc
TlsAlloc 分配一个 TLS 索引供后续在该索引上存取数据。
3.2 访问 TLS 数据TlsGetValue 和 TlsSetValue
TlsGetValue从指定的 TLS 索引获取数据。TlsSetValue在指定的 TLS 索引上存储数据。
3.3 释放 TLS 索引TlsFree
TlsFree 释放先前分配的 TLS 索引。
示例使用 TLS 存储线程局部数据
#include windows.h
#include iostreamDWORD tlsIndex;DWORD WINAPI ThreadFunc(LPVOID lpParam) {int localData *(int*)lpParam; // 每个线程独立的数据TlsSetValue(tlsIndex, (LPVOID)localData);int* pData (int*)TlsGetValue(tlsIndex);std::cout Thread local data: *pData std::endl;return 0;
}int main() {tlsIndex TlsAlloc(); // 分配 TLS 索引if (tlsIndex TLS_OUT_OF_INDEXES) {return 1;}int threadData[2] { 10, 20 };HANDLE hThread1 CreateThread(nullptr, 0, ThreadFunc, threadData[0], 0, nullptr);HANDLE hThread2 CreateThread(nullptr, 0, ThreadFunc, threadData[1], 0, nullptr);WaitForSingleObject(hThread1, INFINITE);WaitForSingleObject(hThread2, INFINITE);CloseHandle(hThread1);CloseHandle(hThread2);TlsFree(tlsIndex); // 释放 TLS 索引return 0;
}4. 同步机制
4.1 临界区Critical Section
临界区用于保护共享资源防止多个线程同时访问同一资源。相比互斥体临界区的性能更高但只适用于单一进程内的线程同步。
InitializeCriticalSection初始化临界区。EnterCriticalSection进入临界区。LeaveCriticalSection离开临界区。DeleteCriticalSection删除临界区。
示例使用临界区保护共享资源
#include windows.h
#include iostreamCRITICAL_SECTION cs;
int counter 0;DWORD WINAPI ThreadFunc(LPVOID lpParam) {for (int i 0; i 10000; i) {EnterCriticalSection(cs);counter;LeaveCriticalSection(cs);}return 0;
}int main() {InitializeCriticalSection(cs);HANDLE hThread1 CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);HANDLE hThread2 CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);WaitForSingleObject(hThread1, INFINITE);WaitForSingleObject(hThread2, INFINITE);std::cout Final counter value: counter std::endl;CloseHandle(hThread1);CloseHandle(hThread2);DeleteCriticalSection(cs);return 0;
}4.2 互斥体Mutex
互斥体是用于多进程同步的对象。它比临界区更通用但性能略低。
CreateMutex创建或打开一个命名的互斥体对象。ReleaseMutex释放互斥体。
示例使用互斥体同步线程
#include windows.h
#include iostreamHANDLE hMutex;DWORD WINAPI ThreadFunc(LPVOID lpParam) {WaitForSingleObject(hMutex, INFINITE); // 请求互斥体std::cout Thread running with mutex protection. std::endl;Sleep(1000); // 模拟工作ReleaseMutex(hMutex); // 释放互斥体return 0;
}int main() {hMutex CreateMutex(nullptr, FALSE, nullptr); // 创建互斥体HANDLE hThread1 CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);HANDLE hThread2 CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);WaitForSingleObject(hThread1, INFINITE);WaitForSingleObject(hThread2, INFINITE);std::cout Both threads have completed. std::endl;CloseHandle(hThread1); // 关闭线程句柄CloseHandle(hThread2);CloseHandle(hMutex); // 关闭互斥体句柄return 0;
}4.3 信号量Semaphore
信号量控制一组资源的访问权限可以限制多个线程同时访问一个或多个资源。
CreateSemaphore创建信号量对象。ReleaseSemaphore释放信号量。
示例使用信号量控制线程访问资源
#include windows.h
#include iostreamHANDLE hSemaphore;DWORD WINAPI ThreadFunc(LPVOID lpParam) {WaitForSingleObject(hSemaphore, INFINITE); // 请求信号量std::cout Thread is accessing a limited resource. std::endl;Sleep(1000); // 模拟工作ReleaseSemaphore(hSemaphore, 1, nullptr); // 释放信号量return 0;
}int main() {hSemaphore CreateSemaphore(nullptr, 2, 2, nullptr); // 创建信号量初始值和最大值均为2HANDLE hThread1 CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);HANDLE hThread2 CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);HANDLE hThread3 CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr); // 第三个线程将等待// 等待所有线程完成WaitForSingleObject(hThread1, INFINITE);WaitForSingleObject(hThread2, INFINITE);WaitForSingleObject(hThread3, INFINITE);std::cout All threads have completed. std::endl;CloseHandle(hThread1);CloseHandle(hThread2);CloseHandle(hThread3);CloseHandle(hSemaphore); // 关闭信号量句柄return 0;
}4.4 事件Event
事件对象用于线程之间的信号传递允许一个线程通知一个或多个线程某个事件的发生。
CreateEvent创建事件对象。SetEvent设置事件为信号状态。ResetEvent将事件重置为非信号状态。
示例使用事件同步线程
#include windows.h
#include iostreamHANDLE hEvent;DWORD WINAPI ThreadFunc(LPVOID lpParam) {std::cout Thread waiting for event... std::endl;WaitForSingleObject(hEvent, INFINITE); // 等待事件被设置std::cout Thread proceeding after event! std::endl;return 0;
}int main() {hEvent CreateEvent(nullptr, FALSE, FALSE, nullptr); // 创建手动重置事件HANDLE hThread CreateThread(nullptr, 0, ThreadFunc, nullptr, 0, nullptr);if (hThread) {Sleep(2000); // 模拟一些工作std::cout Setting event. std::endl;SetEvent(hEvent); // 释放线程WaitForSingleObject(hThread, INFINITE); // 等待线程完成CloseHandle(hThread);}CloseHandle(hEvent); // 关闭事件句柄return 0;
}5. 纤程Fibers
纤程是比线程更轻量级的执行单元允许程序在用户空间中管理调度。纤程的创建和切换比线程更快适合某些特定的高性能应用。
5.1 纤程的基本操作
ConvertThreadToFiber将当前线程转换为纤程。CreateFiber创建纤程。SwitchToFiber切换到指定的纤程。DeleteFiber删除纤程。
示例使用纤程
#include windows.h
#include iostreamVOID CALLBACK FiberFunc(ULONG_PTR lpParam) {std::cout Fiber is running! std::endl;
}int main() {// 将主线程转换为纤程PVOID pFiber ConvertThreadToFiber(nullptr);if (pFiber nullptr) {std::cerr Failed to convert thread to fiber. std::endl;return 1;}// 创建新的纤程PVOID pNewFiber CreateFiber(0, FiberFunc, nullptr);if (pNewFiber nullptr) {std::cerr Failed to create fiber. std::endl;return 1;}// 切换到新的纤程SwitchToFiber(pNewFiber);// 切换回原纤程SwitchToFiber(pFiber);// 删除新创建的纤程DeleteFiber(pNewFiber);return 0;
}6. 总结 通过以上内容我们详细展示了 C 中 Windows API 的多线程支持包括线程的创建、控制、优先级管理、线程局部存储、各种同步机制临界区、互斥体、信号量、事件以及纤程的使用。每个示例都展示了如何使用相关的 Windows API帮助你加深理解和掌握多线程编程的技巧。希望这些示例能够帮助你在开发高性能和高并发的应用程序时更得心应手。通过掌握这些技术开发者能够构建高效、稳定的多线程应用充分利用现代硬件的并发能力提升应用程序的性能。希望本文能够为 C 开发者提供有益的指导和实践经验助力提升在 Windows 平台下的多线程编程能力。 上一篇学懂C二十九高级教程——深入解析 C 异步任务和 Futuresstd::future、
下一篇学懂C三十一高级教程——深入详解C高级多线程编程技术之锁优化与替代