There you are designing a parallel algorithm, and then it occurs to you: How do I return information to the main thread from a child thread?
If you’ve skimmed through half of The C++ Programming Language (4th Edition) by Bjarne Stroustrup like I have, you may recall a section about futures and promises which are related to threads.
Well those are exactly what we need, although I am sure you could create a custom solution. Like perhaps locking and inserting your data into an external container. Perhaps you prefer a standard C++ answer to your problems though? This way it makes sense and you need less comments.
My case was that I wished to learn the “proper” way to do it, and boy did I have a time learning.
Let’s get to the bottom line.. std::promise and std::future are the “proper” way to extract processed data from a thread. So how does one do that?
Well here is an excerpt from my WordSearch project.
struct ThreadResults //Might as well package these together { std::future<std::vector<FoundWord>> future; std::promise<std::vector<FoundWord>> promise; }; using std::thread; using Task = std::pair < thread*, ThreadResults* >; //This is practically a comment already std::vector<Task> Task_List; //We need threads to extract from for ( auto search_word_list : Search_Words ) { //Our Puzzle Words are grouped by size for ( int i = search_word_list.first; i <= largest_search_area; ++i ) { //search_word_list.first is the size of words in the list //We only want search areas big enough for the word to fit in if ( Search_Areas.find( i ) != Search_Areas.end() ) { std::vector<WordBoxWord>& search_area_list = Search_Areas[i]; ThreadResults* shared_state = new ThreadResults; //You need to associate the promise to the future. That is why promise::get_future() exists shared_state->future = shared_state->promise.get_future(); //This is the part that got me. You need to std::move( promise ) in order to pass it to a new thread. //I tried passing by reference. Pointer.. you name it. This is how you do it! std::thread *T = new std::thread( SearchAlg, std::move( shared_state->promise ), search_word_list.second, std::ref( search_area_list ) ); Task_List.push_back( std::make_pair( T, shared_state ) ); } } } //While there are tasks we haven't checked on while ( Task_List.size() != 0 ) { auto task = Task_List.begin(); task->first->join(); // These are threads we're dealing with.. gotta join them back auto results = task->second->future.get(); // EXTRACTION!! WOO for ( auto word_iterator = results.begin(); word_iterator != results.end(); ++word_iterator ) { this->Words_Found.push_back( *word_iterator ); } delete task->first;// thread delete task->second; // data //Task data is saved and pointers deleted, erase the task Task_List.erase( task ); }