boost::future-是否保证wait_callback只被调用一次
boost::future - Is wait_callback guaranteed to only be invoked once?
如果在boost::unique_future
上设置set_wait_callback
,它是否保证只运行一次?
我有点怀疑,因为当查看源代码时,我发现以下内容:
struct relocker
{
boost::unique_lock<boost::mutex>& lock;
relocker(boost::unique_lock<boost::mutex>& lock_):
lock(lock_)
{
lock.unlock();
}
~relocker()
{
lock.lock();
}
private:
relocker& operator=(relocker const&);
};
void do_callback(boost::unique_lock<boost::mutex>& lock)
{
if(callback && !done)
{
boost::function<void()> local_callback=callback;
relocker relock(lock); // unlock mutex?
local_callback();
}
}
void wait(bool rethrow=true)
{
boost::unique_lock<boost::mutex> lock(mutex);
do_callback(lock);
while(!done)
{
waiters.wait(lock);
}
if(rethrow && exception)
{
boost::rethrow_exception(exception);
}
}
在do_callback
中,当回调被调用时,互斥对象实际上是解锁的,根据我的理解,如果多个线程调用wait
函数,这可能会导致回调被多次调用?
可以多次调用回调吗?它是故意的吗?还是我错过了什么?
我有点惊讶的原因是,在C++11标准中,async(std::launch::deferred, ...)
(set_wait_callback
是其表亲)似乎有一个单独的调用保证:
§30.6.8
在功能完成之前,共享状态不会准备就绪。对引用该共享状态的异步返回对象应调用调用等待函数的线程中的延迟函数。
我认为你的怀疑是有根据的。代码应该看起来像
void do_callback(boost::unique_lock<boost::mutex>& lock)
{
if(callback && !done)
{
boost::function<void()> local_callback=callback;
callback=boost::function<void()>;
relocker relock(lock); // unlock mutex?
local_callback();
}
}
甚至
void do_callback(boost::unique_lock<boost::mutex>& lock)
{
if(callback && !done)
{
boost::function<void()> local_callback=boos::move(callback);
relocker relock(lock); // unlock mutex?
local_callback();
}
}
一旦Boost.Function将支持move语义。
这还有一些问题,因为另一个线程可能会调用set_wait_callback,所以可以重新分配回调,并且可以调用两个回调。似乎需要一个额外的状态来说明回调是否已经完成。
void do_callback(boost::unique_lock<boost::mutex>& lock)
{
if(callback && ! callback_done && !done)
{
boost::function<void()> local_callback=callback;
callback_done=true;
relocker relock(lock); // unlock mutex?
local_callback();
}
}
顺便说一句,set_wait_callback不是线程安全的。
template<typename F,typename U>
void set_wait_callback(F f,U* u)
{
callback=boost::bind(f,boost::ref(*u));
}
并且必须受到保护
template<typename F,typename U>
void set_wait_callback(F f,U* u)
{
boost::lock_guard<boost::mutex> lock(mutex);
callback=boost::bind(f,boost::ref(*u));
}
请,你能为Boost Thread创建一个Trac票证,这样这个问题就不会丢失吗?
相关文章:
- 循环中的条件:为什么每次都调用strlen(),而vector.size()只调用一次
- 为什么 zlib 放气初始化调用一次不起作用?
- 什么是仅调用一次并调用参数的控制台应用
- 谷歌基准测试,如何只调用一次代码?
- Android JNI RegisterNatives:对所有内容调用一次,或者每个函数调用一次
- 系统调用:一次和多次,哪个更好?
- C++菱形问题 - 如何仅调用一次基方法
- 函数被多次执行,同时调用一次
- 只为NOT STATIC类的EACH对象调用一次方法
- 通过调用一次新运算符大容量分配对象
- Boost::asio::async_write,处理程序只调用一次
- 为什么析构函数被调用两次,而构造函数只被调用一次
- 强制子类实现并调用(一次)方法
- 等待中的谓词在循环中使用notify时只调用一次
- boost::future-是否保证wait_callback只被调用一次
- 为什么这个函数只被调用一次
- Qpid质子on_sendable只被调用一次
- 每次选择参数时调用一次的静态变量和函数
- 如何只执行一次方法代码,尽管每帧调用一次
- 在c++中调整vector大小时调用一次类构造函数