【发布时间】:2015-06-23 09:39:48
【问题描述】:
我有一个相当通用的工作队列。它需要一定数量的std::function<void(void)> 并在 N 个工作线程上执行它们。闭包 + 类型擦除效果很好。
但是,现在我希望函数“返回”某些状态,并且我希望队列对可能的类型一无所知。为此,我正在考虑使用一个队列
std::function <std::function<void(void)>(void)>
如果我可以保持语法正确的话,它是一个接受 void 并返回一个接受 void 并返回 void 的函数。想法是添加第二个工作队列以返回任务执行的结果。
虽然这并不能严格解决问题 - 然后我可以调用返回的值,但这显然不允许我检索状态。
我可以返回 boost::any,它似乎没有告诉我包含的类型是什么,或者 boost::variant,这意味着为任务库提供所有可能返回类型的列表。两者似乎都不理想。
我想做的是对解释函数调用结果所需的信息进行编码,但我没有看到实现此目的的干净方法。将一个 execute() 和一个 extract() 方法捆绑到一个 void(void) 函子中,这超出了我的狡猾。
另一种解决方法是异构工作队列,但是用 C++ 编写这样的东西也很痛苦。我感到乐观的是,有一个惯用的解决方案可以解决执行类型擦除代码导致的未知类型,但猜测搜索关键字对我来说并不顺利。指导将不胜感激。
编辑:应用程序代码的预期工作流程大纲,与工作队列/线程池层不同
- 构造一个或多个异步执行的任务
- 将任务打包为
std::function</*consistent type*/> - 推入库提供的队列
- 暂时做一些其他的事情
- 从队列中检索某种不透明类型
- 将此不透明类型传递给一个函数,以计算出它的实际含义
- 一切从这里开始
edit:正如 cmets 中所建议的,类型擦除是双向的。 让泛型函子为:
struct functor
{
typedef std::function<void(void)> functype;
functype async;
functype result;
};
然后使用queue<functor> 的实例进行发送和接收。异步在远程线程上运行。当函子的一个实例返回时,我们不知道它代表什么,但是 result() 成员可以执行并且可以执行任何被认为合理的下一步。这可能就足够了。
【问题讨论】:
-
你能详细说明调用者会做什么任意的、可能未知的状态返回类型吗?
-
@Mark B - 感谢您的提问。通常,将其传递给函数,静态访问者样式。例如。 print() 执行某种形式的猜测类型,然后调用类型特定的 print() 函数或方法。无论异步任务队列的用户喜欢什么。
-
只需使用
boost::any。它有一个type()成员函数,它返回它所包含的东西的typeid。 -
有什么方法可以使用静态或动态多态性来防止
6需要知道具体类型? -
@Mark B - 这是正确的提示。动态多态性之所以有效,是因为返回值都是相同的(基本)类型。所以让我们使用一致的类型,即
struct {typedef std::function<void(void)> func; func async; func result; };当一个实例从线程池中返回时,我们不知道 async() 是什么,但是 result() 知道,这就足够了。太棒了:)
标签: c++