用C++11多线程库thread创建线程

一、函数方式

  1. thread
    C++11标准线程库,创建线程:
thread mythread(函数名);
thread mythread(函数名,参数列表);
thread mythread(类对象);
  1. join()
    mythread.join();
    阻塞主线程,让主线程等待子线程执行完毕,然后和主线程回合,主线程继续向下执行。
  2. detach()
    mythread.detach();
    主线程和子线程分离,主线程和子线程同时执行,主线程不必等待子线程结束,子线程进入后台(守护线程),由运行时库接管。
  3. joinable()
    mythread.joinable()
    判断是否可以join或者detach,返回true,可以join可以detach, 返回false, 不能join不能detach

示例

#include 
#include 
using namespace std;

void myprint(int n) {
    cout << "我的线程开始了" << endl;
    // ....
    for (int i = 0; i < n; i++) {
        cout << "--->子线程第" << i + 1 << "项操作。" << endl;
    }
    cout << "我的线程结束了" << endl;
}
int main() {
    const int n = 10;
    thread mythread(myprint, n);
    //mythread.join(); //阻塞主线程,让主线程等待子线程执行完毕,然后和主线程回合,主线程继续向下执行。
    mythread.detach(); //主线程和子线程分离,主线程和子线程同时执行,主线程不必等待子线程结束,子线程进入后台(守护线程),由运行时库接管。
    /*
    注意事项:detach分离后,主线程如果先结束,子线程如果还用到主线程的资源则会出错,比如引用
    */
    for (int i = 0; i < n; i++) {
        cout << "main thread" << endl;
    }
    cout << "主线程结束!" << endl;
    
    return 0;
}

二、可执行的类对象

#include 
#include 
using namespace std;

class TA {
public:
    int &m_i; //bug, 一旦使用了detach,主线程先结束,引用的地址就会出现不可预料的结果,要么食用join方式,要么用拷贝(不要用引用)
    TA(int &i) :m_i(i) {
        cout << "constructor" << endl;
    }
    TA(const TA& ta) :m_i(ta.m_i) {
        cout << "copy constructor" << endl;
    }
    ~TA() {
        cout << "deconstructor" << endl;
    }
    void operator() () {
        
        cout << "m_i的值:" << m_i << endl;
        cout << "m_i的值:" << m_i << endl;
    }
};
int main() {
    int i = 1;
    TA ta(i);
    thread mythread(ta);
    //mythread.join(); //阻塞主线程,让主线程等待子线程执行完毕,然后和主线程回合,主线程继续向下执行。
    mythread.detach(); //主线程和子线程分离,主线程和子线程同时执行,主线程不必等待子线程结束,子线程进入后台(守护线程),由运行时库接管。
    /*
    注意事项:detach分离后,主线程如果先结束,子线程如果还用到主线程的资源则会出错,比如引用
    主线程结束后,ta对象会被销毁,但是不影响子线程,因为ta对象是被复制到线程中去的
    */
    for (int i = 0; i < 10; i++) {
        cout << "main thread" << endl;
    }
    cout << "主线程结束!" << endl;

    return 0;
}

踩坑事项:数据最好拷贝到子线程中去,要使用引用的话,必须用join方式。

三、lamda表达式

#include 
#include 
using namespace std;

int main() {
    auto mylamda = [] {
        cout << "lamda方式的子线程" << endl;
    };
    thread mythread(mylamda);
    //mythread.join(); //阻塞主线程,让主线程等待子线程执行完毕,然后和主线程回合,主线程继续向下执行。
    mythread.detach(); //主线程和子线程分离,主线程和子线程同时执行,主线程不必等待子线程结束,子线程进入后台(守护线程),由运行时库接管。
    
    for (int i = 0; i < 10; i++) {
        cout << "main thread" << endl;
    }
    cout << "主线程结束!" << endl;

    return 0;
}

你可能感兴趣的:(用C++11多线程库thread创建线程)