并发队列推送函数的C ++返回值

时间:2013-01-29 10:54:25

标签: c++ multithreading concurrency c++11 promise

在收到关于登录其他线程的上一个问题的答案后,我目前处于以下代码位置(注意:此处的concurrent_queue来自ppl,但任何其他concurrent_queue应该有效):

class concurrentFuncQueue
    {
    private:
        typedef std::function<void()> LambdaFunction;
        mutable concurrency::concurrent_queue<LambdaFunction> functionQueue;
        mutable std::atomic<bool> endcond;
        LambdaFunction function;
        std::thread thd;
    public:
        concurrentFuncQueue() : endcond(false), thd([=]{
            while (endcond != true)
            {
                if (functionQueue.try_pop( function ))
                {
                    function(); //note: I am popping a function and adding () to execute it
                }
            }
        }){}
        ~concurrentFuncQueue() { functionQueue.push([=]{ endcond = true; }); thd.join(); }
        void pushFunction(LambdaFunction function) const { functionQueue.push(function); }
    };

基本上我推送的函数按顺序在不同的线程上运行(例如记录函数),以避免主线程出现性能问题。

目前的用法如下:

static concurrentFuncQueue Logger;
vector<char> outstring(256);
Logger.pushFunction([=]{ OutputDebugString(debugString.c_str()) });

到目前为止很棒。我可以将函数推送到并发队列,该队列将在一个单独的线程上顺序运行我的函数。

我还需要有一件事,但目前不是返回值,所以ex(伪代码):

int x = y = 3;
auto intReturn = Logger.pushFunction([=]()->int { return x * y; });

将x * y推送到并发队列,并在弹出并完成该函数后(在另一个线程上),将计算出的值返回给调用者线程。

(我知道我将阻止调用程序线程,直到返回推送的函数。这正是我想要的)

我觉得我可能不得不使用std :: promise中的某些东西,但遗憾的是我目前对它们的理解不足以阻止我制定可编码的东西。

有什么想法吗?关于上述C ++代码和任何其他注释的想法也非常受欢迎(如果您觉得另一个实现更合适或解决了问题,请完全忽略代码。)

1 个答案:

答案 0 :(得分:3)

你应该可以使用以下内容:

template<typename Foo>
std::future<typename std::result_of<Foo()>::type> pushFunction(Foo&& f) {
    using result_type = typename std::result_of<Foo()>::type; // change to typedef if using is not supported
    std::packaged_task<result_type()> t(f);
    auto ret_fut = t.get_future();
    functionQueue.push(std::move(t));
    return ret_fut;
}

为此,您需要使LambdaFunction成为类型擦除的函数处理程序。