C++11 thread library (three) create a thread

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.

Guess you like

Origin blog.csdn.net/weixin_39258979/article/details/114193227