A method to start a thread in a C++ program

  • 2020-04-02 03:10:11
  • OfStack

  I will try to introduce you to a new thread library, C++11, which includes tools for starting and managing threads and provides methods for synchronizing (mutexes, locks, and atomic variables).

If you want to compile the code in this article, you'll need at least one compiler that supports C++11. I'm using GCC 4.6.1, which requires either -c++0x or -c++11 arguments to enable C++11 support.

Starting a thread

It is very easy to start a thread in C++11. You can use STD :thread to create a thread instance, which will be started automatically after it is created. All you need to do is pass a pointer to the function to execute.

 


#include <thread>
#include <iostream>
 
void hello(){
  std::cout << "Hello from thread " << std::endl;
}
 
int main(){
  std::thread t1(hello);
  t1.join();
 
  return 0;
}


All of the thread-related methods are defined in the thread header file, and what's interesting is that the code above calls the join() function, which forces the main thread to wait for the thread to finish executing before exiting. If you didn't write join(), the result might be a Hello from thread and a new line, or no new line. Because the master thread may return before the thread finishes executing.

The thread identifier

Each thread has a unique ID to identify different threads. The STD :thread class has a get_id() method that returns the unique number of the corresponding thread. You can access the current thread instance through STD ::this_thread.
 


#include <thread>
#include <iostream>
#include <vector>
 
void hello(){
  std::cout << "Hello from thread " << std::this_thread::get_id() << std::endl;
}
 
int main(){
  std::vector<std::thread> threads;
 
  for(int i = 0; i < 5; ++i){
    threads.push_back(std::thread(hello));
  }
 
  for(auto& thread : threads){
    thread.join();
  }
 
  return 0;
}


Start each thread in turn, then save them to a vector container, the program execution results are unpredictable, for example:


  Hello from thread 140276650997504
  Hello from thread 140276667782912
  Hello from thread 140276659390208
  Hello from thread 140276642604800
  Hello from thread 140276676175616

It could be:


  Hello from thread Hello from thread Hello from thread 139810974787328Hello from thread 139810983180032Hello from thread
  139810966394624
  139810991572736
  139810958001920

Or something else, because the execution of multiple threads is interlaced. There is no way you can control the order of execution of threads (otherwise, why threads?).


You don't have to create a function for a thread to execute when there's only a little bit of code to execute, you can use lambda to define the code to execute, so the first example can be rewritten as:
 


#include <thread>
#include <iostream>
#include <vector>
 
int main(){
  std::vector<std::thread> threads;
 
  for(int i = 0; i < 5; ++i){
    threads.push_back(std::thread([](){
      std::cout << "Hello from thread " << std::this_thread::get_id() << std::endl;
    }));
  }
 
  for(auto& thread : threads){
    thread.join();
  }
 
  return 0;
}

Here we use a lambda expression to replace the function pointer, and the result is the same.


Related articles: