c++11在語言層面上提供了對thread的支持,由於不同的平臺提供了不同線程API,在語言層面提供了對thread的支持可以大大的減小代碼移植的工作量。
- thread的構造函數參數爲函數名和可變參數,請看栗子
- thread的默認構造函數創建一個沒有執行過程的線程,該線程既不可以被join,也沒有id,如果join將會產生terminated
- 不可以被拷貝和賦值,拷貝構造函數和賦值函數都被thread聲明爲private函數,無法調用,你可能會說既然這樣那默認構造函數還有什麼用,別忘了c++11的新特性,move構造函數還可以用的呀,下面的栗子中將有展示
- 一個thread對象在join了之後,將不能再join,joinable爲false,同時get_id也爲0
- 可以用joinable函數來判斷thread是否可以被join
- detach可以和主線程分離,主線程將會失去控制權,經過實驗主線程結束後detach的線程也結束,但是不會產生異常了
#include <iostream>
#include <thread>
#include <stdlib.h>
void sum(int a, int b) {
std::cout<<a + b<<std::endl;
}
void mySleep() {
std::this_thread::sleep_for(std::chrono::milliseconds(1000*30));
}
int main() {
std::thread t(sum, 99, 1);
std::cout<<"t.joinable:"<<t.joinable()<<std::endl;
std::cout<<"t.get_id "<<t.get_id()<<std::endl;
t.join();
std::cout<<"after t.join"<<std::endl;
std::cout<<"t.joinable:"<<t.joinable()<<std::endl;
std::cout<<"t.get_id "<<t.get_id()<<std::endl;
std::thread emptyTh;
//std::thread t1 = emptyTh;//Error
//std::thread t2(emptyTh);//Error
std::cout<<"emptyTh.joinable:"<<emptyTh.joinable()<<std::endl;
std::cout<<"emptyTh.get_id "<<emptyTh.get_id()<<std::endl;
//emptyTh.join();//terminated
std::thread t3(mySleep);
t3.detach();
return 0;
}
this_thread
std::this_thread是用在線程內部調用的,主要有以下api
- get_id獲取當前線程id
- yield讓出線程自己的cpu
- sleep_for睡眠絕對時間
- sleep_utile睡眠至絕對時間
下面直接粘貼官方栗子了
// this_thread::yield example
#include <iostream> // std::cout
#include <thread> // std::thread, std::this_thread::yield
#include <atomic> // std::atomic
std::atomic<bool> ready (false);
void count1m(int id) {
while (!ready) { // wait until main() sets ready...
std::this_thread::yield();
}
for (volatile int i=0; i<1000000; ++i) {}
std::cout << id;
}
int main ()
{
std::thread threads[10];
std::cout << "race of 10 threads that count to 1 million:\n";
for (int i=0; i<10; ++i) threads[i]=std::thread(count1m,i);
ready = true; // go!
for (auto& th : threads) th.join();
std::cout << '\n';
return 0;
}