Linux/POSIX 等同于 Win32 的 CreateEvent、SetEvent、WaitForSingleObject
Linux/POSIX equivalent for Win32's CreateEvent, SetEvent, WaitForSingleObject
我写了一个小的 class 用于同步 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 的等价物是什么。
到目前为止,我已经根据 this SO question 编写了以下 class,但由于答案不完整,我不确定如何完成我的 class :
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()
{
}
};
同时检查 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
您描述的 POSIX 等效项是 POSIX 条件变量。请注意,条件变量必须始终与 POSIX 互斥量一起使用,但多个条件变量经常使用相同的互斥量,因此如果您不打算专门为条件变量使用互斥量,则应该不要将它放在 class 中。在您的情况下,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。
与您的代码等效的 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 使用类似键的文件路径来缩进事件,我不认为所有这些答案都是好的。
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事件消息队列可以解决大部分请求,但它不提供超时能力,当你不想完全冻结你的process/thread时,这可能会导致一些问题。 12=]
我写了一个小的 class 用于同步 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 的等价物是什么。 到目前为止,我已经根据 this SO question 编写了以下 class,但由于答案不完整,我不确定如何完成我的 class :
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()
{
}
};
同时检查 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
您描述的 POSIX 等效项是 POSIX 条件变量。请注意,条件变量必须始终与 POSIX 互斥量一起使用,但多个条件变量经常使用相同的互斥量,因此如果您不打算专门为条件变量使用互斥量,则应该不要将它放在 class 中。在您的情况下,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。
与您的代码等效的 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 使用类似键的文件路径来缩进事件,我不认为所有这些答案都是好的。
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事件消息队列可以解决大部分请求,但它不提供超时能力,当你不想完全冻结你的process/thread时,这可能会导致一些问题。 12=]