在c++11中,类似于node.js/javascript回调的线程

Is in c++11 something similar for threads to node.js/javascript callbacks?

本文关键字:javascript 回调 线程 js node c++11 类似于      更新时间:2023-10-16

如果我从主线程启动一个线程,是否有任何选项可以挂起新线程将要触发的回调。回调应该在主线程中执行。

目前我正在使用future来执行此任务,但我想避免等待结果(结果是布尔值,在true的情况下一切正常,在false的情况下我需要重新启动线程来尝试执行任务)。在c++11中有类似于node.js/javascript回调的东西吗?

当前标准C++中,没有任何明确的方法可以做到这一点。

std::future::then()在标准化管道中,可以包含在C++1y或TR中

有几个第三方库支持这种习惯用法:

  • Boost.Thread
  • 英特尔线程构建块(TBB)
  • OpenMP
  • Microsoft并行模式库(PPL)[仅限Windows]
  • Microsoft卡萨布兰卡

相关:Asio是一个C++异步I/O库,它只支持非阻塞I/O操作,而不是一般的计算操作。(Node.js主要用于I/O,所以这可能就足够了。)

否则,您可以推出自己的解决方案:

auto myFuture = std::async([](){
    doWork();
}).share();
auto myNextFuture = std::async([=](){
    myFuture.wait();
    doMoreWork();
});

你可以把它打包成一个可重复使用的助手:

template <typename Future, typename Work>
auto after(Future f, Work w) -> std::future<decltype(w())>
{
    return std::async([=]() -> decltype(w()) { f.wait(); return w(); });
}

并像这样使用:

auto myFuture = std::async([](){
    doWork();
});
auto myNextFuture = after(myFuture.share(), [](){
    doMoreWork();
});

使用这种方法,您可能需要支付额外线程的成本。

相关:Herb Sutter的C++并发对话。

std::future::then()和Oktalist的continuation implementations listet将做得很好,如果你真的不需要在主线程中执行回调的话。但如果这是一项要求,那就不够了。

如果您有一个正在运行的事件循环(大多数GUI应用程序都会有一个),您可以从继续通知循环执行回调。

在Qt中,您可以从continuation内部向主线程中的对象发送信号。事件循环最终将执行主线程中的插槽。

如果你没有事件循环,提升协同程序可能是一个选择,但我自己没有使用过。

创建一个任务队列以在主线程中运行。将其设置为多作者一读者线程安全(在CS文本或网络上有许多这样的实现)。

队列应该在非空时发出信号,并允许读取器等待

让您的线程将任务排入此队列。让主剧院等待。

如果主线程必须同时做其他事情,请将这些任务排入同一线程。也就是说,如果您响应用户输入,则让读取线程的用户输入将任务抛到表示要处理的用户输入的队列中。

出于响应性的原因,处理用户输入的线程应该避免复杂的计算。

这种技术被称为"消息泵"——"主"线程为消息泵(任务队列)提供服务,按顺序处理每个消息(排队的任务)。在工业规模的应用程序中,每次都发送抽象请求,而不是显式任务,并进行消息的元处理(回退处理程序等)。

您的"在主线程上运行"包括向主线程查询一条消息,该消息表示"运行此任务"。

"传统"C++程序的主线程不是消息泵,因此注入代码运行是不可行的。大多数gui框架都有一个uou可以挂接的消息泵系统。由于javascript是一种以ui为中心的语言,所以main thead隐含地提供了类似于消息泵的服务。