事件
什么是事件?
事件是指系统或应用程序中发生的特定动作或状态变化,这些动作或变化可以被程序检测并响应。Windows 采用事件驱动的编程模型,应用程序主要通过处理各种事件来与用户交互
我们来看一下事件的函数
HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, // 安全描述符BOOL bManualReset, // TRUE通知,FALSE为互斥BOOL bInitialState, // TRUE有信号,FALSE没有信号LPCWSTR lpName // 名称
);
#include<iostream>
#include<windows.h>HANDLE g_hEvent;DWORD WINAPI ThreadProcOne(LPVOID lpParameter) {WaitForSingleObject (g_hEvent, INFINITE);std::cout << "ThreadProcOne执行了\n";return 0;
}DWORD WINAPI ThreadProcTwo(LPVOID lpParameter) {WaitForSingleObject(g_hEvent, INFINITE);std::cout << "ThreadProcTwo执行了\n";return 0;
}int main() {// 创建事件g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);HANDLE hThread[2];// 创建两个线程hThread[0] = CreateThread(NULL, 0, ThreadProcOne, NULL, 0, NULL);hThread[1] = CreateThread(NULL, 0, ThreadProcTwo, NULL, 0, NULL);// 设置事件为已通知SetEvent(g_hEvent);// 等待线程结束,销毁内核对象WaitForMultipleObjects(2, hThread, TRUE, INFINITE);CloseHandle(hThread[0]);CloseHandle(hThread[1]);CloseHandle(g_hEvent);
}
当bManualReset为TRUE
时,WaitForSingleObject并不会改变互斥的令牌值,其它线程同样也可以执行,当为FALSE
时,WaitForSingleObject则会改变互斥的令牌值,其他线程进入等待状态
线程同步
线程同步是指线程之前所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时才被唤醒(线程互斥是线程同步的前提条件)
同步 = 互斥 + 有序
模拟实现 生产者生产 消费者消费 场景,生产一个,消费一个
#include<iostream>
#include<windows.h>HANDLE g_producer;
HANDLE g_consumer;int g_max = 10;
int g_numbaer = 0;// 生产者线程
DWORD WINAPI ThreadProducer(LPVOID lpParameter) {for (int i = 0; i < g_max; i++) {WaitForSingleObject(g_producer, INFINITE); g_numbaer++;DWORD id = GetCurrentThreadId();std::cout << "生产者执行了,当前线程ID为:" << id << ",当前容量:" << g_numbaer << "\n";SetEvent(g_consumer); // 通知消费者消费 (自己线程挂起,如果还有剩余的cpu时间片未使用完,则直接放弃让给其他线程)}return 0;
}// 消费者线程
DWORD WINAPI ThreadConsumer(LPVOID lpParameter) {for (int i = 0; i < g_max; i++) {WaitForSingleObject(g_consumer, INFINITE);g_numbaer--;DWORD id = GetCurrentThreadId();std::cout << "消费者执行了,当前线程ID为:" << id << ",当前容量:" << g_numbaer << "\n";SetEvent(g_producer); // 通知生产者生产}return 0;
}int main() {// 创建事件生产者一开始就执行生产g_producer = CreateEvent(NULL, FALSE, TRUE, NULL);// 消费者需要等待生产者的事件g_consumer = CreateEvent(NULL, FALSE, FALSE, NULL);HANDLE hThread[2];// 创建两个线程hThread[0] = CreateThread(NULL, 0, ThreadProducer, NULL, 0, NULL);hThread[1] = CreateThread(NULL, 0, ThreadConsumer, NULL, 0, NULL);// 等待线程结束,销毁内核对象WaitForMultipleObjects(2, hThread, TRUE, INFINITE);CloseHandle(hThread[0]);CloseHandle(hThread[1]);CloseHandle(g_producer);CloseHandle(g_consumer);
}