【问题标题】:RXCPP: Timeout on blocking functionRXCPP:阻塞功能超时
【发布时间】:2017-07-12 07:31:29
【问题描述】:

考虑一个阻塞函数:this_thread::sleep_for(milliseconds(3000));

我正在尝试获得以下行为:

Trigger Blocking Function               

|---------------------------------------------X

我想触发阻塞功能,如果时间太长(超过两秒),它应该超时。

我做了以下事情:

my_connection = observable<>::create<int>([](subscriber<int> s) {
    auto s2 = observable<>::just(1, observe_on_new_thread()) |
    subscribe<int>([&](auto x) {
        this_thread::sleep_for(milliseconds(3000));
        s.on_next(1);
    });
}) |
timeout(seconds(2), observe_on_new_thread());

我无法让它工作。对于初学者,我认为 s 不能从不同的线程 on_next。

所以我的问题是,正确的反应方式是什么?如何在 rxcpp 中包装阻塞函数并为其添加超时?

随后,我想获得一个行为如下的 RX 流:

Trigger                Cleanup

|------------------------X
                           (Delay)   Trigger           Cleanup
                                       |-----------------X

【问题讨论】:

  • 我认为可以做到的另一种方法是:auto connection = timeout.amb(blocking_function_observable)

标签: c++11 rxcpp


【解决方案1】:

好问题!上面的很接近。

这是一个如何将阻塞操作适配到 rxcpp 的示例。它确实 libcurl polling 发出 http 请求。

以下内容应该符合您的预期。

auto sharedThreads = observe_on_event_loop();

auto my_connection = observable<>::create<int>([](subscriber<int> s) {
        this_thread::sleep_for(milliseconds(3000));
        s.on_next(1);
        s.on_completed();
    }) |
    subscribe_on(observe_on_new_thread()) |
    //start_with(0) | // workaround bug in timeout
    timeout(seconds(2), sharedThreads);
    //skip(1); // workaround bug in timeout

my_connection.as_blocking().subscribe(
    [](int){}, 
    [](exception_ptr ep){cout << "timed out" << endl;}
);
  • subscribe_on 将在专用线程上运行create,因此允许create 阻塞该线程。
  • timeout 将在另一个线程上运行计时器,该线程可以与其他人共享,并将所有on_next/on_error/on_completed 调用转移到同一线程。
  • as_blocking 将确保 subscribe 在完成之前不会返回。这仅用于防止 main() 退出 - 最常见于测试或示例程序中。

编辑:为timeout 中的错误添加了解决方法。目前,它不会在第一个值到达之前安排第一次超时。

EDIT-2:timeout 错误已修复,不再需要解决方法。

【讨论】:

  • 嗨,柯克,感谢您对此的意见。我运行了您建议的代码 sn-p。似乎on_nexton_error 之前触发。我怀疑this_thread::sleep_for() 正在阻止超时启动内部计时器。如果 s.on_completed 被删除,on_next 将在超时后触发 on_error
  • 这就是我没有先尝试的结果。我在超时运算符中发现了一个错误,我已经用该错误的解决方法更新了答案。
  • 我合并了一个修复 timeout 的 PR。不再需要解决方法!保留解决方法会产生一些较小的开销,但除此之外仍然可以使用固定的timeout
猜你喜欢
  • 1970-01-01
  • 2014-04-24
  • 2017-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-16
  • 1970-01-01
  • 2016-10-18
相关资源
最近更新 更多