In the article C++11 Thread Library (1) Constructor and its members, we know that we have the following construction methods:
thread() noexcept;//since c++11
thread(thread&& other) noexcept;//since c++11
template<class Function,class ...Args>
explicit thread(Function &&f,Args && ...args);//since c++11
thread(const thread&)=delete;//since c++11
There are a total of four, the first is the default construction, which constructs a thread object that does nothing; the second is the move constructor that std::move() will call; the third is a class template, which means the use of a function object Generate the corresponding thread class with several parameters; the fourth is the copy constructor, which cannot be copied by default.
The third is the basic method of creating a thread object, he needs
- A function object
- Zero or more parameters
Function objects can be generated from function templates, which are defined as:
template< class >
class function; /* undefined */
(since C++11)
template< class R, class... Args >
class function<R(Args...)>;//用R类实例化函数对象
Given a class and corresponding parameters, the class template generates a std::function class. The class R parameter of the template has certain requirements. Common classes that meet the requirements are:
- Ordinary function
- lambda expression
- bind expression
- Other callable objects (such as functors)
- Member function pointer
- Member function data members (class data members?)
Notes
The arguments to the thread function are moved or copied by value. If a reference argument needs to be passed to the thread function, it has to be wrapped (e.g. with std::ref or std::cref).
Any return value from the function is ignored. If the function throws an exception, std::terminate is called. In order to pass return values or exceptions back to the calling thread, std::promise or std::async may be used.
Example: Create two threads to print odd and even numbers respectively
#include <iostream>
#include <thread>
using namespace std;
void show_even()
{
for(int i=0;i<10;i+=2)
{
cout<<i;
}
};
void show_odd()
{
for(int i=1;i<10;i+=2)
{
cout<<i;
}
}
int main()
{
thread th1(show_odd);
thread th2(show_even);
th1.join();
th2.join();
return 0;
}
The results of each run is different, take any of three results: 0246813579
1357902468
1350247968
. The cpu will only execute in one thread at a time. If the processing speed is simple enough, it is possible that all the content of one thread is completed, but the other thread has not yet started.
For a simple execution content, it is more appropriate to use lambda to create a callable object:
int main()
{
thread th1([](){
for(int i=0;i<10;i+=2){
cout<<i;}});
thread th2([](){
for(int i=1;i<10;i+=2){
cout<<i;}});
th1.join();
th2.join();
return 0;
}
No need to think about the function name, no need to write a special function, blabla.