c++11多線程編程(第三講)

 

#include <iostream>
#include <thread>
#include <string>
using namespace std;

 //自己創建一個線程,也需要從一個函數開始運行;
//void my_print(const int i, char *p_myBuf)
void my_print(const int i, const string &p_myBuf)
{
    cout<<"i:"<<i<<endl;
    //分析認爲,i並不是m1的引用,實際是值傳遞,那麼即使主線程結束,也不是影響子線程的這個變量的使用
    cout<<"p_myBuf:"<<p_myBuf<<endl;
    //指針在deatch子線程時,絕對會有問題,所以這邊一定不能傳指針
    return;
}
int main()
{
    /*
   一:傳遞零時對象作爲線程參數
    (2.1)只要用臨時構造的A類對象作爲參數傳遞給線程,那麼就一定能夠在主線程執行完畢前把線程函數的參數構造出來
    若傳遞int這樣的簡單類型參數,建議都是值傳遞,不要使用引用,仿真主線程結束變量被釋放造成問題。
    如果傳遞類對象,避免隱式轉換。全部都在創建線程這一行就構建出臨時對象來,然後在函數參數裏使用引用來接。
    如果不使用引用,那麼會多調用一次拷貝構造函數。
    (2.2)
    二:臨時對象作爲線程參數
    線程id的概念: id是一個數字,每個線程(不管是主線程還是子線程)實際上都對應着一個數字。
    不同線程的id必然是不一樣的。
    線程id可以用c++標準庫中的函數來獲取std:this_thread::get_id();
    */
    int m1=1;
    int &m2 = m1;
    char mybuf[] = "this is a test!";
    //實際上mybuf被回收了(main執行完了)系統才用mybuf轉成string,這樣會出問題
    //std::thread my_thread4(my_print, m1, mybuf);
    將mybuf轉換成一個零時對象,這樣就能保證不出問題。
    std::thread my_thread4(my_print, m1, string(mybuf));
    //my_thread4.join();
    my_thread4.detach();//子線程和主線程分別執行
    cout << "Hello world!" << endl;
    return 0;
}

-----------------------------------------------------------------------------------------------------------------------------

 

 

#include <iostream>
#include <thread>
#include <string>
using namespace std;

class A
{
public:
    int m_i;
    A(int i):m_i(i)
    {
        cout << "構造函數執行了"<<this<<" thread ID:"<<std::this_thread::get_id()<< endl;
    }
    A(const A &a1):m_i(a1.m_i)
    {
        cout << "拷貝構造函數執行" <<this<<" thread ID:"<<std::this_thread::get_id()<< endl;
    }
    ~A()
    {
        cout << "析構函數執行" <<this<<" thread ID:"<<std::this_thread::get_id()<< endl;
    }
    void operator()()//不能帶參數
    {
        cout << "我的線程 operator執行了" << endl;
        cout << "m_i的值爲:"<<m_i<< endl;

    }
};

void myprint2(const A &pmybuf)
{
    cout<<"子線程 myprint2參數地址"<<&pmybuf
        <<"threadid:"<<std::this_thread::get_id()<<endl;
}

int main()
{
    /*
    (2.2)
    二:臨時對象作爲線程參數
    線程id的概念: id是一個數字,每個線程(不管是主線程還是子線程)實際上都對應着一個數字。
    不同線程的id必然是不一樣的。
    線程id可以用c++標準庫中的函數來獲取std::this_thread::get_id();

    */
    cout<<"主線程ID:"<<this_thread::get_id()<<endl;
    int m1=1;
    //在主線程中使用臨時對象來傳遞,就會線程安全。
    //傳遞類對象時就使用引用接收主線程中創建線程時的臨時對象,這樣能確保線程安全和少調用一次拷貝構造函數。
    std::thread my_thread5(myprint2,A(m1));

    char mybuf[] = "this is a test!";
    //my_thread5.join();
    my_thread5.detach();//子線程和主線程分別執行
    cout << "Hello world!" << endl;
    return 0;
}

 

智能指針作爲線程函數的參數
void my_print(unique_ptr<int> pIn)//線程函數
{
    cout<<"my_print"<<<<"threadId:"<<std::this_thread::get_id()<<endl;
    
}

int main()
{
    unique_ptr<int> pInt(new int(100));
    std::thread myjob_th(my_print,std::move(pInt));
    myjob_th.join();
    //myjob_th.detach();
    
    
    return 0;
}

 

 

發佈了92 篇原創文章 · 獲贊 71 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章