【问题标题】:How to add a folly function with arguments into an folly executor?如何将带有参数的愚蠢函数添加到愚蠢的执行器中?
【发布时间】:2019-03-16 06:12:44
【问题描述】:

我正在尝试在 folly::ThreadedExecutor 中添加一些正常的作业,它们是 folly::Function。但是,folly::ThreadedExecutor 似乎只提供接受 folly::Function<void()> 的接口。如何添加带有参数和输出的函数?

// Here's a simple code segment

#include <folly/executors/ThreadedExecutor.h>
#include <folly/futures/Future.h>

int my_func(int t) {
   sleep(t);
   return 1;
}

int main() {
   folly:ThreadedExecutor executor;
   folly:Function<int(int)> job = my_func;
   executor.add(job);  
}

gcc -o folly_executor --std=c++14 -g -O0 -Wall folly_executor.cc -lgtest -lfolly -lpthread -lglog -lgflags -ldl -ldouble-conversion -levent -liberty -lboost_context编译

错误表示add 函数原型在executormy_func 中不匹配。以下是编译错误。

In file included from folly_executor.cc:2:0:
/usr/local/include/folly/executors/ThreadedExecutor.h:67:8: note: 
candidate: virtual void folly::ThreadedExecutor::add(folly::Func)
   void add(Func func) override;
        ^~~
/usr/local/include/folly/executors/ThreadedExecutor.h:67:8: note:   no 
known conversion for argument 1 from 'folly::Function<int(int)>' to 
'folly::Func {aka folly::Function<void()>}'

不知道add函数原型的限制是否有必要的原因。如果不是,那一定是正确的做法。

顺便说一句,tutorial 和 Github 上的文档总是使用 folly::executor 和 folly:Future。我应该以这种方式使用 folly:Function 吗?

【问题讨论】:

  • 在创建Minimal, Complete, and Verifiable Example 时,请确保生成您遇到的错误的是实际代码!您显示的当前代码将有错误,但不是您询问的那些。
  • 感谢您的评论。我已经编辑了我的问题。如果需要,我会提供更多额外信息。

标签: c++ multithreading folly


【解决方案1】:

感谢 Alex Bakulin 的answer。我用folly::Future 接口解决了我的问题,以下是我的示例代码。就我而言,我将FutureAtomicHashMap 一起使用。使用Future 可以通过folly::viastd::bind 轻松提供输入和访问输出。但是我仍然对他们为什么缩小Folly::Function 的使用范围感到困惑,并希望它只用于存储没有任何输入和输出的可调用对象。

#include <folly/executors/CPUThreadPoolExecutor.h>
#include <folly/futures/Future.h>
#include <folly/AtomicHashMap.h>


folly::Future<int> my_func(int t, folly::AtomicHashMap<int, int>& ahm) {
    ahm.insert(std::make_pair(t, t*2));
    return 1;
}

int main() {
    folly::CPUThreadPoolExecutor executor(8);
    folly::AtomicHashMap<int, int> ahm(4096);
    for (int i = 0; i < 3; i++) {
        folly::Future<int> f = folly::via(&executor, std::bind(my_func, i, std::ref(ahm)));
    }
    executor.join();

    for (int i = 0; i < 3; i++) {
        auto ret = ahm.find((i));
        int r = ret != ahm.end() ? ret->second : 0;
        std::cout << i << "th result is "<< r << std::endl;
    }
    return 0;
}

【讨论】:

    【解决方案2】:

    您可能已经自己弄清楚了,但为了完整起见,我会给出一个答案。 ThreadedExectutor 是一个非常低级的东西,它只是在单独的线程中为你运行东西。当您安排某个函数运行时,您无法控制它返回的时间和内容。如果您需要做的只是让函数调用发生在一个单独的线程中,您可以将此调用包装在一个匿名函数中,并使用执行程序期望的签名:

    executor.add([]() { my_func(123); });
    

    如果您的目标也是捕获调用的输出,那么您最好使用futures,它具有更高的抽象级别,并为您提供更丰富的原语集来工作与。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-09
      • 2011-06-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多