如何将带有参数的愚蠢函数添加到愚蠢的执行器中?



我正在尝试添加一些正常的作业,这些作业是愚蠢的::函数在愚蠢::线程执行器。但是,似乎 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编译

该错误表示addexecutormy_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()>}'

我想知道添加函数原型的限制是否有必要的理由。如果没有,那一定是一种正确的方法。

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

感谢亚历克斯·巴库林的回答。我用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;
}

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

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

如果你的目标也是捕获调用的输出,那么你最好使用期货,它处于更高的抽象级别,并为你提供了一组更丰富的原语。

相关内容

最新更新