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;
}