在Linux下替代Windows特定的HANDLE、事件创建和同步API的方法

3

我有一组特定于Windows的代码如下:

    //1: Declaring HANDLE
    HANDLE *m_handle;
    
   //2: Creating HANDLE instance   
   int m_Count = 4;
   m_handle = new HANDLE[m_Count];

   //3: Creating Events
   for (int i = 0; i < m_Count ; i++)
    {
        m_handle [i] = CreateEvent(NULL, FALSE, FALSE, NULL);
    }

   //4: Synchronous API
   DWORD dwEvent = WaitForMultipleObjects(m_Count, m_handle, TRUE, 30000);

   //5: Closing the HANDLE
   for (int i = 0; i < m_Count; i++)
    {
        CloseHandle(m_handle[i]);
    }

如何在 Linux 上编写相同的代码?


2
你究竟想要做什么? - Asteroids With Wings
1
在Linux中没有类似Windows事件对象的完全相同物。在概念上有几个类似的设施,例如基本条件变量、事件文件描述符和命名管道,具有等待一个或多个对象被触发的各种能力。一般来说,你不能将使用MS-Windows API的东西逐行改写成Linux等效物。这两个操作系统在根本上是不同的。 - Sam Varshavchik
嗨。感谢回复。我基本上正在执行多线程操作。在这里,我创建的事件数量等于线程实例的数量。我试图在线程下调用各种需要事件句柄作为参数的方法。这些方法将执行指定的操作并设置事件以指示操作已完成。接下来,我将检查在给定时间内是否完成了该进程。最后,我将在析构函数中销毁句柄。我需要在Linux上执行相同的操作。 - Sharath Kumar
在Linux下并不存在“事件句柄”这种东西。因此,你的第一步将是完全摆脱这个概念,而是专注于它们提供的功能。接下来你需要做的是研究条件变量(这是C++核心库的一部分,而不是Linux特有的),以及Linux特有的事件文件描述符和epoll()系统调用,了解它们的工作原理,并确定它们是否适合你的需求。 - Sam Varshavchik
你的方法可能是错误的。不要试图在Linux或Windows上模仿对方。先阅读Advanced Linux Programming,然后查看syscalls(2),再学习Pthread教程。或者使用跨平台框架(如Qt...)。 - Basile Starynkevitch
显示剩余2条评论
1个回答

7
替代CreateEvent的是eventfd,你可能需要使用EFD_CLOEXECEFD_NONBLOCK标志。除非你知道自己在做什么,否则不要使用信号量标志。
替代WaitForMultipleObjects的是poll,在请求的事件中指定POLLIN标志。请记住,事件不会被poll重置,它将保持已通知状态。Read 8个字节从eventfd句柄中以重置计数器。该功能与Windows上的手动重置事件相同。
要发出事件信号,请在eventfd句柄上调用write,并传递一个值为1的本地uint64_t变量的地址。
一旦你不再需要事件,只需调用close即可销毁它们。

更新:我刚刚注意到您正在向WaitForMultipleObjects传递bWaitAll=TRUE

不幸的是,Linux的poll无法完全做到这一点。它会在超时到期或至少有1个句柄变为已信号状态时返回,取决于哪种情况先发生。

不过,解决方法并不太难。您可以通过在循环中多次调用poll来模拟bWaitAll,直到所有事件都被标记为已信号状态。无需重建句柄数组,对于在poll返回后变为已信号状态的事件,可以将文件句柄设置为负值。请注意,可能会同时有多个事件被标记为已信号状态,poll返回值告诉您其中有多少个。还要记得减少超时值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接