Linux/POSIX 相当于 Win32 的 CreateEvent、SetEvent、WaitForSingleObject
- 2024-11-11 08:27:00
- admin 原创
- 25
问题描述:
我编写了一个小类,用于同步 Linux(实际上是 Android)和 Windows 的线程。
这是我的接口的 Win32 实现:
class SyncObjectWin32 : public SyncObject
{
private:
const HANDLE m_hEvent;
public:
SyncObjectWin32()
: m_hEvent( ::CreateEvent( NULL, FALSE, FALSE ) )
{
if( NULL == m_hEvent )
throw core::Exception( "sys::SyncObjectWin32::SyncObjectWin32() - Failed to create event." );
}
~SyncObjectWin32()
{
::CloseHandle( m_hEvent );
}
void WaitForSignal()
{
::WaitForSingleObject( m_hEvent );
}
void Signal()
{
::SetEvent( m_hEvent );
}
};
问题是我不确定什么是 POSIX 等效项。到目前为止,我已经根据这个 SO 问题编写了以下课程,但由于答案不完整,我不确定如何完成我的课程:
class SyncObjectPosix
{
private:
pthread_mutex_t m_oMutex;
public:
SyncObjectPosix()
{
pthread_mutex_lock( m_oMutex ); // lock mutex
bool & signalled = find_signal( condition ); // find predicate
signalled = true; // set predicate
pthread_mutex_unlock( m_oMutex ); // unlock mutex
pthread_cond_signal( condition ); // signal condition variable
}
~SyncObjectPosix()
{
}
void WaitForSignal()
{
pthread_mutex_lock(mutex); // lock mutex
bool & signalled = find_signal( condition ); // find predicate
while (!signalled)
{
pthread_cond_timedwait(condition, m_oMutex, timeout);
}
signalled = false; // reset predicate
pthread_mutex_unlock( m_oMutex ); // unlock mutex
}
void Signal()
{
}
};
解决方案 1:
您所描述的 POSIX 等效项是 POSIX 条件变量。请注意,条件变量必须始终与 POSIX 互斥锁配对使用,但很多时候多个条件变量使用同一个互斥锁,因此如果您不打算将互斥锁专门用于条件变量,则不应将其放在类中。您的案例中 Win32 和 POSIX API 之间的映射含义应为:
CreateEvent
->pthread_cond_init
CloseHandle
->pthread_cond_destroy
WaitForSingleObject
->pthread_cond_wait
或pthread_cond_timedwait
SetEvent
->pthread_cond_signal
或pthread_cond_broadcast
幸运的是,有很多关于这方面的文档,但我推荐基本的编程 POSIX 线程。
解决方案 2:
也检查一下eventfd
。这似乎几乎相当于CreateEvent
如果你只需要一个消费者和一个生产者。
CreateEvent
-->eventfd
CloseHandle
-->close
SetEvent
-->write
WaitForSingleObject
-->read
WaitForMultipleObjects
-->select
和read
对应的 fd
更多阅读材料
http://www.sourcexr.com/articles/2013/10/26/lightweight-inter-process-signaling-with-eventfd
解决方案 3:
您的代码的 pthreads 等效内容是:
class SyncObjectPosix
{
private:
bool signalled;
pthread_mutex_t mutex;
pthread_cond_t cond;
public:
SyncObjectPosix()
{
signalled = false;
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
}
~SyncObjectPosix()
{
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
}
void WaitForSignal()
{
pthread_mutex_lock(&mutex);
while (!signalled)
{
pthread_cond_wait(&cond, &mutex);
}
signalled = false;
pthread_mutex_unlock(&mutex);
}
void Signal()
{
pthread_mutex_lock(&mutex);
signalled = true;
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond);
}
};
解决方案 4:
我们的开源pevents
库就是针对所有平台的实现。它是一小段(单文件)C++ 代码,您可以将其添加到现有项目中,并访问基于 pthreads 同步原语构建的 Windows 事件 API。
最重要的一点是它包含WaitForMultipleObjects
支持。
https://github.com/neosmart/pevents
解决方案 5:
由于 Win32 的 CreateEvent 使用类似键的文件路径来缩进事件,所以我认为所有这些答案都不好。
检查UNIX:System V IPC
int project_id = 1;
std::string path = "[path]";
//CreateEvent
key_t ipc_key = ftok(path.c_str(),project_id);
int event_id = msgget(ipc_key , IPC_CREAT);
//OpenEvent
key_t ipc_key = ftok(path.c_str(),project_id);
int event_id = msgget(ipc_key , 0);
//SetEvent
std::string send_message = "trump 2024|America first|life equally matter|build the #$% wall"; //
msgsnd(event_id, send_message.c_str(), send_message.size(), IPC_NOWAIT); //NO Block
msgsnd(event_id, send_message.c_str(), send_message.size(), 0); //Block
//WaitForSingleObject
std::string receive_message;
receive_message.resize(128);
msgrcv(event_id , &receive_message[0], receive_message.size(), 0,0);
//CloseHandle
msgctl(event_id , IPC_RMID,NULL);
请注意,即使某些函数每次调用的速度可能更快,但是基于文件描述的函数并不像 CreateEvent 那样与进程间兼容。
使用IPC事件消息队列可能解决大多数请求,但它不提供超时功能,当您有时不想完全冻结进程/线程时,这可能会导致一些问题。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件