雪傲天1 2023-05-24 15:38 采纳率: 96.2%
浏览 14
已结题

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);这两个有什么区别吗?我觉得一样呀

```

  • 写回答

1条回答 默认 最新

  • @晓码自在 2023-05-24 17:02
    关注

    该回答引用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用于线程间通信,而不直接作用于发出该信号的线程本身。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 6月1日
  • 已采纳回答 5月24日
  • 创建了问题 5月24日