[英]Why does not this simple Producer-Consumer program using two boost::fibers work as expected?
[英]Producer/Consumer using Boost.Fibers
我正在尝试使用Boost.Fibers创建生产者/消费者。 看起来使用此示例中的channels
是正确的事情。 由于我想使用promise/future
表示完成,因此必须稍微更改示例。 所以我写了一些幼稚的代码,不做任何工作,只是示意完成。
struct fiber_worker {
fiber_worker() {
wthread = std::thread([self{this}]() {
for (int i = 0; i < 4; ++i) {
boost::fibers::fiber{
[self]() {
task tsk;
while (boost::fibers::channel_op_status::closed != self->ch.pop(tsk)) {
tsk();
}
}}.detach();
}
task tsk;
while (boost::fibers::channel_op_status::closed != self->ch.pop(tsk)) {
tsk();
}
});
}
boost::fibers::future<void> submit() noexcept {
boost::fibers::promise<void> prom;
auto retVal = prom.get_future();
ch.push([p{std::move(prom)}]() mutable { p.set_value(); });
return retVal;
}
~fiber_worker() {
ch.close();
wthread.join();
}
using task = std::function<void()>;
std::thread wthread;
boost::fibers::buffered_channel<task> ch{1024};
};
但是,它将无法编译,它将抱怨正在访问被删除的promise
删除副本构造函数。 首先,我不知道在哪里(以及为什么)要调用复制构造函数。 其次,我不确定这是应该使用boost::fibers
的方式。
用法
int main() {
fiber_worker bwk;
bwk.submit().get();
}
错误讯息
在/ usr / include / c ++ / 7 / future:48:0中包含的文件中,从/home/user/Downloads/boost_1_66_0/boost/fiber/exceptions.hpp:12,从/ home / user / Downloads / boost_1_66_0 / boost /fiber/future/future.hpp:17,来自/home/user/Development/Tests/shared_state_test/main.cpp:4:/usr/include/c++/7/bits/std_function.h:在实例化'static void std :: _ Function_base :: _ Base_manager <_Functor> :: _ M_clone(std :: _ Any_data&,const std :: _ Any_data&,std :: false_type)[with _Functor = fiber_worker :: submit():: ;; std :: false_type = std :: integral_constant]':/usr/include/c++/7/bits/std_function.h:227:16:需要从'static bool std :: _ Function_base :: _ Base_manager <_Functor> :: _ M_manager( std :: __ Any_data&,const std :: __ Any_data&,std :: _ Manager_operation)[with _Functor = fiber_worker :: submit()::]'/usr/include/c++/7/bits/std_function.h:695:19:必填来自'std :: function <_Res(_ArgTypes ...)> :: function(_Functor)[with _Functor = fiber_worker :: submit()::; =无效; =无效; _Res = void; _ArgTypes = {}]'/home/user/Development/Tests/shared_state_test/main.cpp:45:66:
从这里需要/usr/include/c++/7/bits/std_function.h:192:6:错误:使用删除的函数'fiber_worker :: submit()::: :( const fiber_worker :: submit()::& )'new _Functor( __source._M_access <_Functor >()); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ / home / user /Development/Tests/shared_state_test/main.cpp:45:36:注意:'fiber_worker :: submit()::: :( const fibre_worker :: submit()::&)'被隐式删除,因为默认定义为格式不正确:ch.push(p {std :: move(prom)}可变{p.set_value();}); ^ /home/user/Development/Tests/shared_state_test/main.cpp:45:36:错误:使用删除的功能'boost :: fibers :: promise :: promise(const boost :: fibers :: promise&)'在文件中包含在/home/user/Development/Tests/shared_state_test/main.cpp:5:0:/home/user/Downloads/boost_1_66_0/boost/fiber/future/promise.hpp:192:5:注意:在此处声明promise(答应const&)= delete; ^ ~~~~~~
EDIT001:频道似乎无法使用移动的lambda
struct test {
test() = default;
test(const test &rhs) = delete;
test &operator=(const test &rhs)= delete;
test(test &&rhs) = default;
test &operator=(test &&rhs)= default;
size_t _1 = 0;
size_t _2 = 0;
size_t _3 = 0;
size_t _4 = 0;
void print() const {
std::cout << _1 << _2 << _3 << 4 << std::endl;
}
};
int main() {
using task = std::function<void()>;
boost::fibers::buffered_channel<task> ch{1024};
test tst;
ch.push([t{std::move(tst)}]() { t.print(); });
}
将联系boost :: fibers维护者进行澄清
EDIT002: boost::fibers::buffered_channel
没问题,这是我的阿尔茨海默病的唯一问题,我(再次)忘记了std::function
必须是可复制的,并且当lambda仅捕获可移动类型std::function
创建时复制失败
我认为问题不在于未缓冲的通道不能传递可移动的项(push的重载之一是T &&),而是要求它们是默认可构造的,以便它可以使用以下元素预先填充队列:将推送的项目移入。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.