天天看點

C++11:線程線程的建立回收線程資源擷取線程ID和CPU核心數

在C++11之前,C/C++一直是一種順序的程式設計語言。順序是指所有指令都是串行執行的,即在相同的時刻,有且僅有單個CPU的程式計數器執行代碼的代碼段,并運作代碼段中的指令。而C/C++代碼也總是對應地擁有一份作業系統賦予程序的包括堆、棧、可執行的(代碼)及不可執行的(資料)在内的各種記憶體區域。

而在C++11中,一個相當大的變化就是引入了多線程的支援。這使得C/C++語言在進行線程程式設計時,不比依賴第三方庫。

線程的建立

用std::thread建立線程非常簡單,隻需要提供線程函數或函數對象即可,并且可以同時指定線程函數的參數。

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

void func1()
{
    while()
    {
        cout << __func__ << endl;
    }
}

void func2()
{
    while()
    {
        cout << __func__  << endl;
    }
}


int main()
{
    thread t1(func1);   //子線程1
    thread t2(func2);   //子線程2

    while()//主線程
    {
        cout << __func__ << endl;
    }

    return ;
}
           

線程還可以接收任意個數的參數:

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

void func(int a, char ch, const char *str)
{
    std::cout << "a = " << a << "\n";
    std::cout << "ch = " << ch << "\n";
    std::cout << "str = " << str << "\n";
}

int main()
{
    std::thread t(func, , 'a', "mike");   //子線程, 需要頭檔案#include <thread>

    while(); //特地寫一個死循環,讓程式不結束

    return ;
}
           

運作結果如下:

C++11:線程線程的建立回收線程資源擷取線程ID和CPU核心數

回收線程資源

std::thread::join等待線程結束(此函數會阻塞),并回收線程資源,如果線程函數有傳回值,傳回值将被忽略。

#include <iostream>       // std::cout
#include <thread>         // std::thread, std::this_thread::sleep_for
#include <chrono>         // std::chrono::seconds
using namespace std;

void pause_thread(int n)
{
    //指定目前線程休眠一定的時間
    this_thread::sleep_for(chrono::seconds(n));
    cout << "pause of " << n << " seconds ended\n";
}

int main()
{
    cout << "Spawning 3 threads...\n";
    thread t1(pause_thread, );
    thread t2(pause_thread, );
    thread t3(pause_thread, );

    cout << "Done spawning threads. Now waiting for them to join:\n";

    t1.join();//等待線程結束(此函數會阻塞)
    t2.join();
    t3.join();
    cout << "All threads joined!\n";

    return ;
}
           

運作結果如下:

C++11:線程線程的建立回收線程資源擷取線程ID和CPU核心數

如果不希望線程被阻塞執行,可以調用線程的std::thread::detach,将線程和線程對象分離,讓線程作為背景線程去執行。但需要注意的是,detach之後就無法在和線程發生聯系了,比如detach之後就不能再通過join來等待執行完,線程何時執行完我們也無法控制。

#include <iostream>       // std::cout
#include <thread>         // std::thread, std::this_thread::sleep_for
#include <chrono>         // std::chrono::seconds
using namespace std;

void pause_thread(int n)
{
    this_thread::sleep_for (chrono::seconds(n));
    cout << "pause of " << n << " seconds ended\n";
}

int main()
{
    cout << "Spawning and detaching 3 threads...\n";
    thread(pause_thread,).detach();
    thread(pause_thread,).detach();
    thread(pause_thread,).detach();
    cout << "Done spawning threads.\n";

    cout << "(the main thread will now pause for 5 seconds)\n";

    // give the detached threads time to finish (but not guaranteed!):
    pause_thread();

    return ;
}
           

運作結果如下:

C++11:線程線程的建立回收線程資源擷取線程ID和CPU核心數

擷取線程ID和CPU核心數

#include <iostream>       // std::cout
#include <thread>         // std::thread, std::this_thread::sleep_for
#include <chrono>         // std::chrono::seconds
using namespace std;

void func()
{
    this_thread::sleep_for (chrono::seconds());//休眠1秒
    //擷取目前線程id
    cout << "func id = " << this_thread::get_id() << endl;
}

int main()
{
    thread t(func);
    cout << "t.get_id() = " << t.get_id() << endl; //擷取線程t的id
    cout << "main id = "<<this_thread::get_id() << endl; //主線程id
    cout << "cup num = " << thread::hardware_concurrency() << endl;//擷取cpu核心數,失敗傳回0

    t.join(); //線程阻塞

    return ;
}
           

運作結果如下:

C++11:線程線程的建立回收線程資源擷取線程ID和CPU核心數

參考資料:深入應用C++11 代碼優化與工程級應用

繼續閱讀