事件可以完全控制,其他无法控制线程的执行顺序,但是事件对象可以做到。
***事件(Event)***是在线程同步中最常使用的一种同步对象,事件包含一个使用计数,一个是用来表示自动重置/手动重置的布尔值,另一个是表示事件有没有触发的布尔值。
事件对象有两种状态: 1、手动状态。2、自动状态
手动状态事件对象的激发态和非激发态是由我们来控制,自动状态与互斥体类似。

事件对象没有拥有者的概念,谁都可以操作事件对象的状态。事件可以控制线程的执行顺序。
手动状态事件对象的激发态和非激发态是由我们来控制,自动状态与互斥体类似。
在使用正常线程创建调用回调函数时,线程的执行顺序不一定会按线程创建的顺序执行。
#include
#includeLONG g_count;
HANDLE hEvent;
DWORD WINAPI myThreadProc1(_In_ LPVOID lpParameter
)
{printf("线程1执行了\n");return 0;
}DWORD WINAPI myThreadProc2(_In_ LPVOID lpParameter
)
{printf("线程2执行了\n");return 0;
}DWORD WINAPI myThreadProc3(_In_ LPVOID lpParameter
)
{printf("线程3执行了\n");return 0;
}int main()
{//hEvent = CreateEventW(NULL, FALSE, TRUE, L"dsd");HANDLE hThread1 = CreateThread(0, 0, myThreadProc1, 0, 0,0);HANDLE hThread2 = CreateThread(0, 0, myThreadProc2, 0, 0,0);HANDLE hThread3 = CreateThread(0, 0, myThreadProc3, 0, 0,0);WaitForSingleObject(hThread1, -1);WaitForSingleObject(hThread2, -2);printf("%d\n", g_count);CloseHandle(hThread1);CloseHandle(hThread2);return 0;
}

而我们如果使用Event事件就可以对线程的执行顺序进行实现。

信号量也没有拥有者的概念,但是他有数量。
信号量有一个当前信号数,只要这个数不为0,信号量就处于激发态。
当有线程调用WaitForSingle0bject后,信号数减1,如果不为0的话,再有线程调用
WaitForSingleObject.会继续上一把锁。相反调用ReleaseSemaphoore会将信号量加1,。如果信号量为0,当有线程调用WaitForSingleObject.时,线程会被阻塞。
使用场景:多开数量检测
#include
#includeint main() {HANDLE hSema = OpenSemaphoreW(EVENT_ALL_ACCESS, FALSE, L"dsd");//获取信号量句柄if (!hSema)//如果没有成功打开即创建信号量,仅当CreateSemaphore创建信号灯时才会成功{hSema = CreateSemaphore(NULL, 0, 3, L"dsd");//创建或打开信号灯对象,返回信号灯句柄}BOOL hSuccess = ReleaseSemaphore(hSema,1,NULL);//如果成功信号量加1则返回TRUE,否则返回FALSEif (!hSuccess) {MessageBox(0, L"程序打开数量不能超过三个",L"提示",MB_OK);CloseHandle(hSema);return 0;}system("pause");return 0;
}
