C++ thread programming (Linux system as an example) - thread member function and thread creation method

After c++ 11, there is a standard thread library: std::thread.
Refer to the use of thread library

member function

Constructor

The thread constructor has the following four overloads

default constructor

thread() noexcept

initialize constructor

template <class Fn, class... Args>
explicit thread (Fn&& fn, Args&&... args);

This function uses a variadic template to construct a thread object representing a new joinable thread of execution. The execution thread passes variable parameters to the thread function object fn, and the parameter list of the function (it can be simply understood as passing parameters to the constructor by value)

copy constructor

thread (const thread&) = delete;

Thread does not support copy construction

mobile structure

thread(thread&&x) noexcept;

Transfer the ownership of the executable instruction represented by the parameter x without affecting the execution of the thread. After the transfer, the parameter x no longer represents any execution thread.

destructor

The destructor is used to destroy the thread. If the thread can be joined, the destructor will call the terminate() function to terminate the thread. Before the thread object is destroyed, it should be joined or detach as much as possible to prevent the execution thread from terminating due to object destruction.

#include<iostream>
#include<thread>
#include<unistd.h>
using namespace std;
void printtHelloWorld(){
    
    
    while(true){
    
    
        cout<<"hello world"<<endl;
        sleep(1);
    }
}

int main(){
    
    
    thread t1(printtHelloWorld);
    sleep(3);
    t1.~thread();
    return 0;
}

insert image description here

operator=

thread& operator= (thread&& rhs) noexcept;
thread& operator= (const thread&) = delete;

The thread object does not allow copy construction, and the same overloading of the assignment operator is essentially a move assignment.


#include<iostream>
#include<thread>
using namespace std;
void printHelloWorld(){
    
    
    cout<<"Hello World!"<<endl;
}
int main(){
    
    
    thread t1;
    t1 = thread(printHelloWorld);
    t1.join();
    return 0;
}

compileg++ test.cpp -std=c++11 -lpthread - o test
insert image description here

joinable

If the thread object represents a thread of execution, it can be joinable.
There are several situations in C++ that cannot be joinable

  • default construction
  • Executed the move operation
  • Executed join or detach
#include<iostream>
#include<thread>
using namespace std;
void printHelloWorld(){
    
    
    cout<<"Hello World!"<<endl;
}
int main(){
    
    
    thread t1;
    if(!t1.joinable()){
    
    
        cout<<"Thread is not joinable! (default constructor)"<<endl;
    }
    t1 = thread(printHelloWorld);
    if(t1.joinable()){
    
    
        cout<<"Thread is joinable! (represents a thread of execution)"<<endl;
        t1.join();
        if(!t1.joinable()){
    
    
            cout<<"Thread is not joinable! (after call join())"<<endl;
        }
    }
    thread t3;
    thread t2(printHelloWorld);
    t3 = move(t2);
    if(!t2.joinable()){
    
    
        cout<<"Thread is not joinable! (after move)"<<endl;
    }
    t3.join();
    return 0;
}

Thread is not joinable! (default constructor)
Thread is joinable! (represents a thread of execution)
Hello World!
Thread is not joinable! (after call join())
Thread is not joinable! (after move)
Hello World!

join

The function returns after the thread is executed. The join function can be used to block the thread that calls this function. After calling this function, the thread object will become non-joinable and can be safely destroyed.

#include<iostream>
#include<thread>
#include<unistd.h>
using namespace std;
void pauseThread(int n){
    
    
    sleep(n);
    std::cout<<"pause of "<<n<<" seconds ended"<<std::endl;
}
int main(){
    
    
    cout<<"spawing 3 threads..."<<endl;
    std::thread t1(pauseThread,1);
    std::thread t2(pauseThread,2);
    std::thread t3(pauseThread,3);
    cout<<"Done spawning threads. Now wait for them to join: "<<endl;
    t1.join();
    t2.join();
    t3.join();
    cout<<"All threads joined!"<<endl;
    return 0;
}

insert image description here

detach

This function separates the executing thread from the calling thread, allowing them to run independently of each other, releasing the resources owned by either thread after it finishes. After calling, the thread object becomes non-joinable and can be destroyed safely.

#include<iostream>
#include<thread>
#include<unistd.h>
using namespace std;
void pauseThread(int n){
    
    
    this_thread::sleep_for(chrono::seconds(n));
    std::cout<<"pause of "<<n<<" seconds ended"<<std::endl;
}
int main(){
    
    
    cout<<"spawing 3 threads..."<<endl;
    std::thread (pauseThread,1).detach();
    std::thread (pauseThread,2).detach();
    std::thread (pauseThread,3).detach();
    cout<<"Done spawning threads. (the main thread will now pause for 5 seconds)"<<endl;
    pauseThread(5);
    return 0;
}

insert image description here

Creation method

Generic function creation

#include<iostream>
#include<thread>
#include<unistd.h>
using namespace std;
void printtHelloWorld(){
    
    
    while(true){
    
    
        cout<<"hello world"<<endl;
        sleep(1);
    }
}

int main(){
    
    
    thread t1(printtHelloWorld);
    sleep(3);
    t1.~thread();
    return 0;
}

class member function creation

Created outside the class

#include<iostream>
#include<thread>
#include<unistd.h>
using namespace std;
class SaySomething{
    
    
public:
    void sayHello(){
    
    
        cout<<"Hello World!\n";
    }
    void saySomething(string str){
    
    
        cout<<str;
    }
    static void sayHelloStatic(){
    
    
        cout<<"Hello static!\n";
    }
};
int main(){
    
    
    SaySomething sh;
    thread t(&SaySomething::sayHello,&sh);                      //需要传入对象的地址
    thread t1(&SaySomething::saySomething,&sh,"Hello cpp!\n");  //需要传入对象的地址和参数
    thread t2(&SaySomething::sayHelloStatic);                   //静态成员函数不需要传入对象的地址,因为静态成员函数不属于对象
    t.join();
    t1.join();
    t2.join();
    return 0;
}

insert image description here

Create a thread object in the class

#include<iostream>
#include<thread>
#include<unistd.h>
using namespace std;
class SaySomething{
    
    
private:
    thread workThread;
    void sayHello(){
    
    
        cout<<"Hello world!\n";
    }
public:
    SaySomething(){
    
    
        workThread=thread(&SaySomething::sayHello,this);  //需要传入对象的地址
    }
    ~SaySomething(){
    
    
        workThread.join();                                //等待线程结束,防止主线程退出时子线程被强制结束
    }
};
int main(){
    
    
    SaySomething saySomething; //Hello World!
    return 0;
}

Created using a function class

Created using a function class

Overload operator() to implement function-like operations

#include<iostream>
#include<thread>
#include<unistd.h>
using namespace std;
class FunctionObject{
    
    
public:
    void operator()(string str){
    
    
        cout << str << endl;
    }
    void operator()(){
    
    
        cout << "Hello World!\n";
    }
};
int main(){
    
    
    FunctionObject fo;
    thread t(fo);                       //无参数版本
    thread t1(fo, "Hello parameter!\n");    //有参数版本
    t.join();
    t1.join();
    return 0;
}

insert image description here

lambda function creation

#include<bits/stdc++.h>
using namespace std;
int main(){
    
    
    thread t([]{
    
    
        cout << "Hello from thread!" << endl;
    });
    t.join();
    return 0;
}

function class creation

Objects instantiated by the function class can wrap callable objects of any of the following types: functions, pointers to functions, pointers to member functions, or function objects of any type (that is, objects whose class defines operator(), including closures)

#include<iostream>
#include<thread>
#include<unistd.h>
#include<functional>
using namespace std;
void add(int a,int b){
    
    
    cout<<"Sum is: "<<a+b<<"\n";
}
int main(){
    
    
    function<void(int,int)> f=add;                          //function类包装add函数
    function<void(void)> f1 = bind(add,15,25);              //function包装一个闭包
    function<void(void)> f2 = [](){
    
    cout<<"from lambda"<<endl;};//function类包装一个lambda函数
    thread t(f,10,20); 
    sleep(1);                                     //需要传递参数,输出Sum is: 30
    thread t1(f1);      
    sleep(1);                                    //无需传参,输出Sum is: 40
    thread t2(f2);                                          //无需传参
    t.join();
    t1.join();
    t2.join();
    return 0;
}

insert image description here

The return value of bind is created

bind can bind functions and parameters into a function object.

#include<iostream>
#include<thread>
#include<unistd.h>
#include<functional>
using namespace std;
void add(int a,int b){
    
    
    cout<<"Sum is: "<<a+b<<"\n";
}
int main(){
    
    
    auto f1 = bind(add,5,10);
    f1();                           // Sum is: 15
    auto f2 = bind(add,placeholders::_1,placeholders::_2);
    f2(10,20);                      // Sum is: 30
    thread t1(f1);
    thread t2(f2,20,30);
    t1.join();                      // Sum is: 15 来自线程的执行结果
    t2.join();                      // Sum is: 50 来自线程的执行结果
    return 0;
}

insert image description here

Guess you like

Origin blog.csdn.net/qaaaaaaz/article/details/130794725