c++ - 在 Linux 的情况下替换 Windows 特定的 HANDLE、事件创建和同步 API
问题描述
我有以下一组特定于 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 的情况下如何编写相同的代码集?
解决方案
CreateEvent 的替代品是eventfd,您可能需要EFD_CLOEXEC
和EFD_NONBLOCK
标志。除非您知道自己在做什么,否则不要使用信号量标志。
WaitForMultipleObjects 的替代品是poll,在请求的事件中指定POLLIN
标志。请记住,事件不会被轮询重置,它将保持信号状态。从 eventfd 句柄中读取8 个字节以进行重置。该功能与 Windows 上的手动重置事件相同。
要发出事件信号,请在句柄上调用write ,并传递值为 1eventfd
的局部变量的地址。uint64_t
要在不再需要它们时销毁事件,只需调用close。
更新:我刚刚注意到你正在传递bWaitAll=TRUE
给WaitForMultipleObjects
.
不幸的是,Linux poll 不能完全做到这一点。它在超时到期或至少 1 个句柄发出信号时返回,以先发生者为准。
不过,解决方法并不难。bWaitAll
您可以通过在循环中多次调用 poll来模拟,直到所有事件都发出信号。无需重建句柄数组,您可以将文件句柄设置为负值,用于在 poll 返回后发出信号的事件。请注意,它们中的多个可能会同时发出信号,轮询返回值说明其中有多少发出信号。也不要忘记减少超时值。
推荐阅读
- java - 为什么 Spring Security 禁止特定资源而不考虑角色?
- node.js - Passport.js 中的 Google 策略是否随着 Google+ 的结束而弃用
- python-3.x - Pytest - 测试用例执行顺序
- django - 如何从另一个场景中的一个步骤执行一个场景?
- sql - 不使用分析进行分组的自加入
- php - JWT 过期。哪种方法最好?
- python - 如何通过带有条件的键对二维列表进行分组?
- condor - 如何为 isilon 存储设置用户吞吐量限制
- java - 代理后面的 Qpid JMS
- eclipse - Eclipse:加载 SSH2 私钥时出错