SetEvent 和ReleaseMutex(hMutex);这两个有什么区别吗?



```c++
#include <stdio.h>
#include <windows.h>
#include <process.h>
int iTickets = 100;
HANDLE g_hEvent;
DWORD WINAPI SellTicketA(void* lpParam)
{
while (1)
{
WaitForSingleObject (g_hEvent, INFINITE );
if (iTickets > 0)
{
Sleep (1);
iTickets--;
printf ("A remain %d\n", iTickets);
}
else
{
break;
}
SetEvent (g_hEvent);
}
return 0;
}
DWORD WINAPI SellTicketB(void* lpParam)
{
while (1)
{
WaitForSingleObject (g_hEvent, INFINITE );
if (iTickets > 0)
{
Sleep (1);
iTickets--;
printf ("B remain %d\n", iTickets);
}
else
{
break;
}
SetEvent (g_hEvent);
}
return 0;//0 内核对象被销毁
}
int main()
{
HANDLE hThreadA, hThreadB;
hThreadA = CreateThread ( NULL , 0 ,SellTicketA, NULL , 0, 0);// 2
hThreadB = CreateThread ( NULL , 0, SellTicketB, NULL , 0, 0);
CloseHandle (hThreadA); //1
CloseHandle (hThreadB);
g_hEvent = CreateEvent ( NULL , FALSE , FALSE , NULL );
SetEvent (g_hEvent);
Sleep (4000);
CloseHandle (g_hEvent);
system ("pause");
return 0;
}
当执行SellTicketA线程时,里面是一个while循环,难道不会在里面把iTickets一直自减直到break吗?
我看AI的解释是假设执行线程A时,第一次WaitForSingleObject,等待主线程里的SetEvent (g_hEvent);
然后执行完毕后,再次SetEvent, 但是线程A里的WaitForSingleObjec不能再接收自己的SetEven
是这个意思吗?它只能等待同步对象返回有效的信号,为什么不能执行线程A后再次执行线程A呢?
另外这个SetEvent 和ReleaseMutex(hMutex);这两个有什么区别吗?我觉得一样呀

```

该回答引用ChatGPT4与博主@晓码自在合作编写:
你的理解是正确的。这里有几个关键点:

  1. WaitForSingleObject等待同步对象(事件)变为有信号状态,然后继续执行。但是,线程自己发出的SetEvent信号不会作用于自己,只会作用于其他等待该事件的线程。所以,线程A发出的SetEvent不会作用于线程A自己的WaitForSingleObject。
  2. SetEvent将事件设置为有信号,ReleaseMutex释放一个互斥锁。它们的作用不同:
    • SetEvent用于线程间同步,通知其他线程某事件发生
    • ReleaseMutex用于保护共享资源,防止多个线程同时访问资源。
  3. 由于1的原因,线程A的while循环不会一直执行,它会在等待事件变为有信号后继续,而自己发出的SetEvent不作用于自己,所以不会陷入死循环。
  4. CloseHandle(hThreadA)会关闭线程A的句柄,但是不会结束线程A的执行。线程A会一直运行直到执行完毕。
  5. 运行结果会是:
A remain 99 
B remain 98
A remain 97
B remain 96
....
A remain 1
B remain 0 

线程A和B会交替运行,将iTickets减到0,然后结束。

所以,总结来说,你对这个多线程同步例子的理解是正确的。SetEvent用于线程间通信,而不直接作用于发出该信号的线程本身。