c++ - thread creation with a member function runs before the object constructor finishes in for loop -


i'm coding simple client/server multithread program. client threads created like

for (int = 0; < 4; i++) {     clients.emplace_back(work_finished, updated[i], free_client_count,i);     client_threads.emplace_back([&]     {         clients[i].work();     }); } 

and initiation parameters are

std::atomic_bool work_finished;     work_finished.store(false);     std::atomic_bool updated[4];     updated[0].store(false);     updated[1].store(false);     updated[2].store(false);     updated[3].store(false);     atomic_int free_client_count;     free_client_count.store(0); 

but these client threads wouldn't run expected, result in invalid memory access during update[i].load(). if create loop create threads, there no problem.

for (int = 0; < 4; i++) {     clients.emplace_back(work_finished, updated[i], free_client_count,i);  } (int = 0; < 4; i++) {     client_threads.emplace_back([&]     {         clients[i].work();     }); } 

then add log information client constructor. turns out client.work() called before constructor finishes, result in invalid memory access of update_recieved.load() because update_recieved not initiated yet.

here comes question: why work called before client constructed when in same loop? , why it's right break client constructor , thread constructor. complete code below

    using namespace std; class client { public:     std::atomic_int& ready_thread_count;     std::atomic_bool& update_recieved;     std::atomic_bool& work_finished;     const int i;     void recieve()     {         try         {             while (!update_recieved.load())             {                 //std::cout << "not recieved " << << std::endl;                 std::this_thread::yield();             }             std::cout << "recieved " << << std::endl;             update_recieved.store(false);         }         catch (std::exception e)         {             std::cout << e.what() << std::endl;         }       }      void compute()     {         //     }     void send()     {         ready_thread_count++;     } public:     client(std::atomic_bool& in_work_finished, std::atomic_bool& in_update_recieved, std::atomic_int& in_free_thread_count,int in_i)         :work_finished(in_work_finished), update_recieved(in_update_recieved), ready_thread_count(in_free_thread_count), i(in_i)     {         std::cout << "client created " << << std::endl;     }      void work()     {         recieve();         while (!work_finished.load())         {             compute();             send();             recieve();         }         send();      } }; class server { public:     std::atomic_int& ready_thread_count;     std::atomic_bool* update_recieved_vector;     std::atomic_bool& work_finished;     const std::chrono::microseconds wait_time;     const int client_number;     int iteration;     void send()     {         (int = 0; < client_number; i++)         {             std::cout << "update client " << << std::endl;             update_recieved_vector[i].store(true);         }     }      void compute()     {         std::this_thread::sleep_for(wait_time);         iteration++;         std::cout << iteration << std::endl;         if (iteration == 50)         {             work_finished.store(true);         }     }      void recieve()     {         while (ready_thread_count.load() != client_number)         {             std::this_thread::sleep_for(wait_time);         }         ready_thread_count.store(0);     } public:     server(std::atomic_int& in_free_thread_count, std::atomic_bool* in_update_recieved_vector, std::atomic_bool& in_work_finished, int in_client_member, int in_wait_time)         :ready_thread_count(in_free_thread_count), update_recieved_vector(in_update_recieved_vector), work_finished(in_work_finished), client_number(in_client_member), wait_time(in_wait_time)     {         iteration = 0;     }      void work()     {         while (!work_finished.load())         {             send();             recieve();             compute();         }         send();         recieve();     } };  int main() {     std::atomic_bool work_finished;     work_finished.store(false);     std::atomic_bool updated[4];     updated[0].store(false);     updated[1].store(false);     updated[2].store(false);     updated[3].store(false);     atomic_int free_client_count;     free_client_count.store(0);     server local_server(free_client_count, updated, work_finished, 4, 20);     vector<client> clients;     vector<thread> client_threads;     thread server_thread(&server::work, &local_server);     (int = 0; < 4; i++)     {         clients.emplace_back(work_finished, updated[i], free_client_count,i);         client_threads.emplace_back([&]         {             clients[i].work();         });     }      server_thread.join();     (int = 0; < 4; i++)     {         client_threads[i].join();     }     std::cout << "finaly" << std::endl; } 


Comments