[英]Linux/POSIX equivalent for Win32's CreateEvent, SetEvent, WaitForSingleObject
我写了一个小类来同步 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 question编写了以下课程,但由于答案不完整,我不确定如何完成我的课程:
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()
{
}
};
您所描述的 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
幸运的是,有很多关于此的文档,但我推荐基本的Programming POSIX Threads 。
还要检查eventfd
。 如果您只需要一个消费者和一个生产者,它似乎几乎等同于CreateEvent
。
CreateEvent
--> eventfd
close
CloseHandle
--> close
SetEvent
--> write
WaitForSingleObject
--> read
WaitForMultipleObjects
--> select
并read
对应的 fd
更多阅读http://www.sourcexr.com/articles/2013/10/26/lightweight-inter-process-signaling-with-eventfd
与您的代码等效的 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);
}
};
我们的开源pevents
库是针对所有平台的实现。 这是一个非常小的(单文件)C++ 代码,您可以将其添加到现有项目中并访问构建在 pthreads 同步原语之上的 Windows 事件 API。
最重要的一点是它包括WaitForMultipleObjects
支持。
由于 Win32 的 CreateEvent 使用类似 key 的文件路径来缩进事件,我认为并不是所有的答案都是好的。
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);
请注意,即使某些函数每次调用可能会获得更高的速度,您可能仍然需要将句柄(文件描述)共享给其他进程,并确保句柄不冲突。 您仍然可以使用IPC消息来共享句柄,然后您切换到一些加速事件功能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.