C ++ return value for simultaneous queue tuning functions

After receiving answers to the previous question when entering another thread, I am in the following bit of code (note: concurrent_queue is here from ppl, but any other concurrent_queue should work):

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); } }; 

Basically, the functions that I click run in another thread sequentially (like a logging function) to avoid performance issues in the main thread.

Current use is as follows:

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

Excellent. I can push functions to a parallel queue, which will sequentially run my functions in a separate thread.

One thing I also need to have, but currently does not return a value, so ex (pseudocode):

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

will move x * y to the parallel queue, and after the pop-up function and completion of the function (in another thread) will return the value calculated for the caller's thread.

(I understand that I will block the caller's thread until the push function is returned). This is exactly what I want)

I get the feeling that I might have to use something along the lines of std :: prom, but, unfortunately, my current poor understanding of them does not allow me to formulate something capable.

Any ideas? Thoughts on the above C ++ code and any other comments are also welcome (please just completely ignore the code if you feel that another implementation is more appropriate or solves the problem).

+4
source share
1 answer

You should be able to use something line by line:

 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; } 

To do this, you need to make your LambdaFunction a function handler of the erasable type.

+3
source

All Articles