繁体   English   中英

与 Win32 的 CreateEvent、SetEvent、WaitForSingleObject 等效的 Linux/POSIX

[英]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_waitpthread_cond_timedwait

SetEvent -> pthread_cond_signalpthread_cond_broadcast

幸运的是,有很多关于此的文档,但我推荐基本的Programming POSIX Threads

还要检查eventfd 如果您只需要一个消费者和一个生产者,它似乎几乎等同于CreateEvent

CreateEvent --> eventfd

close CloseHandle --> close

SetEvent --> write

WaitForSingleObject --> read

WaitForMultipleObjects --> selectread对应的 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支持。

https://github.com/neosmart/pevents

由于 Win32 的 CreateEvent 使用类似 key 的文件路径来缩进事件,我认为并不是所有的答案都是好的。

检查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);

请注意,即使某些函数每次调用可能会获得更高的速度,您可能仍然需要将句柄(文件描述)共享给其他进程,并确保句柄不冲突。 您仍然可以使用IPC消息来共享句柄,然后您切换到一些加速事件功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM