Fir*_*cer 23 c++ windows multithreading boost cross-platform
我正在尝试将一些Windows代码移植到Linux,理想情况是通过独立于平台的库(例如boost),但是我不知道如何移植这些事件代码.
代码位涉及两个线程(让我们称之为A和B).A想要做只有B可以做的事情,所以它向B发送消息,然后等待B说出它完成了.在Windows中,这看起来像:
void foo();//thread a calls this
void bar(HANDLE evt);
void foo()
{
HANDLE evt = CreateEvent(0,FALSE,FALSE,0);
bCall(boost::bind(&bar, evt));
WaitForSingleObject(evt,INFINITE);
CloseHandle(evt);
}
void bar(HANDLE evt)
{
doSomething();
SetEvent(evt);
}
Run Code Online (Sandbox Code Playgroud)
我查看了boost :: thread库,但它似乎没有任何东西可以做到这一点,我可以看到的关闭是boost :: condition_variable,但看起来这意味着与一个互斥量一起使用,但事实并非如此这里.
def*_*ode 15
所有这些答案都太复杂了,对人们来说并不是那么难.
namespace porting
{
class Event;
typedef Event* Event_handle;
static const unsigned k_INFINITE = 0xFFFFFFFF;
class Event
{
friend Event_handle CreateEvent( void );
friend void CloseHandle( Event_handle evt );
friend void SetEvent( Event_handle evt );
friend void WaitForSingleObject( Event_handle evt, unsigned timeout );
Event( void ) : m_bool(false) { }
bool m_bool;
boost::mutex m_mutex;
boost::condition m_condition;
};
Event_handle CreateEvent( void )
{ return new Event; }
void CloseHandle( Event_handle evt )
{ delete evt; }
void SetEvent( Event_handle evt )
{
evt->m_bool = true;
evt->m_cond.notify_all();
}
void WaitForSingleObject( Event_handle evt, unsigned timeout )
{
boost::scoped_lock lock( evt->m_mutex );
if( timeout == k_INFINITE )
{
while( !evt->m_bool )
{
evt->m_cond.wait( lock );
}
}
else
{
//slightly more complex code for timeouts
}
}
}// porting
void foo()
{
porting::Event_handle evt = porting::CreateEvent();
bCall( boost::bind(&bar, evt ) );
porting::WaitForSingleObject( evt, porting::k_INFINITE );
porting::CloseHandle(evt);
}
void bar( porting::Event_handle evt )
{
doSomething();
porting::SetEvent(evt);
}
Run Code Online (Sandbox Code Playgroud)
由于我不熟悉语义WaitForSingleObject(如果两个线程同时调用它会发生什么,如果同一个线程调用它两次会发生什么),可能需要做更多工作才能完全正常工作.但是,解决方案看起来非常像这样.
Ala*_*lan 10
我认为一个好的,跨平台的win32事件等同于boost :: condition,所以你的代码看起来像这样:
void foo()
{
boost::mutex mtxWait;
boost::condition cndSignal;
bCall(boost::bind(&bar, mtxWait, cndSignal));
boost::mutex::scoped_lock mtxWaitLock(mtxWait);
cndSignal.wait(mtxWait); // you could also use cndSignal.timed_wait() here
}
void bar(boost::mutex& mtxWait, boost::condition& cndSignal)
{
doSomething();
cndSignal.notify_one();
}
Run Code Online (Sandbox Code Playgroud)
小智 8
你可以使用一个承诺和未来,来自boost线程:
#include <boost\thread.hpp>
boost::promise<bool> prom;
void foo()
{
auto future = prom.get_future();
auto result = future.wait_for(boost::chrono::milliseconds(1000));
// we get here if (a) 1 second passes or (b) bar sets the promise value
if (result==boost::future_status::ready)
{
/* bar set the promise value */
}
if (result==boost::future_status::timeout)
{
/* 1 second passed without bar setting promise value */
}
}
void bar()
{
prom.set_value(true);
}
Run Code Online (Sandbox Code Playgroud)