Click here to Skip to main content
15,893,486 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Look at this code a little bit:
C++
// packaged_task example
#include <iostream>     // std::cout
#include <future>       // std::packaged_task, std::future
#include <chrono>       // std::chrono::seconds
#include <thread>       // std::thread, std::this_thread::sleep_for

// count down taking a second for each value:
int countdown (int from, int to) {
  for (int i=from; i!=to; --i) {
    std::cout << i << '\n';
    std::this_thread::sleep_for(std::chrono::seconds(1));
  }
  std::cout << "Lift off!\n";
  return from-to;
}

int main ()
{
  std::packaged_task<int(int,int)> tsk (countdown);   // set up packaged_task
  std::future<int> ret = tsk.get_future();            // get future

  std::thread th (std::move(tsk),10,0);   // spawn thread to count down from 10 to 0

  // ...

  int value = ret.get();                  // wait for the task to finish and get result

  std::cout << "The countdown lasted for " << value << " seconds.\n";

  th.join();

  return 0;
}


What I dont understand is how does ret relate to tsk after this line :
C++
std::thread th (std::move(tsk),10,0)
I mean tsk will be null or corrupted after this line, and then one has
C++
int value = ret.get()
which will get something from this null tsk and not from the task inside thread th.
So why does it work?
Posted

1 solution

The future is gotten before the move. So even if the move were to leave tsk in an undefined state, the future that will retrieve the result of the callable (countdown) is already gotten.

move doesn't destroy the parameter, it creates a xvalue, so the thread th will have a valid reference to the callable via the packaged_task.
 
Share this answer
 
Comments
dliviu 10-Feb-15 11:19am    
Thanks for the answer, but I still don't get it. In my opinion, ret is related to tsk. From what you say, I understand that ret is not related to tsk but to the function countdown. But how can this be? I don't understand.
Stefan_Lang 12-Feb-15 9:38am    
No, get_future() creates the data structures necessary to communicate the reuslt of the function back to the ret object. The std::move moves the references to those data structures over to th, so th knows where to put the reuslts. Your concerns would be valid only if get_future were called after the std::move()
dliviu 12-Feb-15 10:20am    
Thank you so very much. Now I understand.
Stefan_Lang 12-Feb-15 10:24am    
You're welcome. Finally I could put that knowledge from the workshop I visited to good use :-)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900