I am analyzing the following code fragment and trying to understand it in detail:
template<typename FUNCTION, typename... ARGUMENTS>
auto ThreadPool::add( FUNCTION&& Function, ARGUMENTS&&... Arguments ) -> std::future<typename std::result_of<FUNCTION(ARGUMENTS...)>::type>
{
using PackedTask = std::packaged_task<typename std::result_of<FUNCTION(ARGUMENTS...)>::type()>;
auto task = std::make_shared<PackedTask>(std::bind(std::forward<FUNCTION>(Function), std::forward<ARGUMENTS>(Arguments)...));
auto ret = task->get_future();
{
std::lock_guard<std::mutex> lock{jobsMutex};
jobs.emplace([task]() { (*task)(); });
}
jobsAvailable.notify_one();
return ret;
}
I have few questions regarding std::packaged_task
.
As you can see in the body of the method add(...)
, an instance std::packaged_task
is task
a local variable whose scale ends with the completion of the method. The return value of the ret
type is std::future
returned by the copy. The value ret
is issued from task
(which is local). Thus, as soon as the execution of the method is completed, it task
goes beyond the scope, and therefore I expect the connected connected instance of std :: future to become invalid, do I understand correctly?
, , std::queue<Job> jobs
. operator()
of std::packaged_task
, Function
, , std::queue
? std::packaged_task
, ...?
, ThreadPool, https://github.com/dabbertorres/ThreadPool , , . , , , , ... , - , ...
, . Cheers Martin