【C++多线程】创建启动线程及查看线程id
创建线程
子线程在创建时启动。使用功能std::thread类创建线程对象。
线程关联的可调对象可以是:普通函数、仿函数对象、Lambda表达式、非静态成员函数、静态成员函数。
示例
普通函数
1 #include <thread> 2 #include <iostream> 3 4 using namespace std; 5 6 void test() 7 { 8 cout << "子线程开始执行!" << endl; 9 //do something 10 cout << "子线程执行完毕!" << endl; 11 } 12 int main() 13 { 14 thread t(test); 15 t.join(); //主线程等待子线程 16 return 0; 17 }
仿函数对象
1 #include <thread> 2 #include <iostream> 3 4 using namespace std; 5 class Test{ 6 public: 7 void operator()(){ 8 cout << "子线程开始执行!" << endl; 9 //do something 10 cout << "子线程执行完毕!" << endl; 11 } 12 13 }; 14 int main() 15 { 16 // thread t(Test()); 这种写法会编译器会认为是一个函数声明,这个函数带有一个参数(函数指针指向没有参数并返回Test对象的函数) 17 thread t((Test())); //可以使用加小括号,或者使用一只初始化,或者传入命名变量 18 t.join(); //主线程等待子线程 19 return 0; 20 }
Lambda表达式
1 #include <thread> 2 #include <iostream> 3 4 using namespace std; 5 6 int main() 7 { 8 thread t( 9 [] () { 10 cout << "子线程开始执行!" << endl; 11 //do something 12 cout << "子线程执行完毕!" << endl; 13 } 14 ); 15 t.join(); //主线程等待子线程 16 return 0; 17 }
非静态成员函数,静态成员函数
以下的下写法中是将对象拷贝了一份副本来创建线程。当我们在进行共享数据的管理时,有时候需要传入对象的指针或者地址。而静态成员函数,不需要传入对象,只需要传入类函数地址。根据C++对象模型,这很好理解因为编译器对非静态成员函数的处理需要this指针,而对静态成员函数的处理不需要。【C++】对象模型之Function
1 #include <thread> 2 #include <iostream> 3 4 using namespace std; 5 class Test{ 6 public: 7 void test(){ 8 cout << "子线程开始执行!" << endl; 9 // do somesthing 10 cout << "子线程执行完毕!" << endl; 11 } 12 }; 13 14 int main() 15 { 16 Test obj; 17 thread t(&Test::test, obj); //注意写法,传入成员函数地址,还需要传入对象 18 t.join(); //主线程等待子线程 19 return 0; 20 }
容器管理多个线程
我们可以使用容器来对多个线程进程管理,为自动化管理线程打下基础。另外std::thread::hardware_concurrency()返回硬件支持并发的线程数量,这里的并发是指硬件可以并行执行多少个线程,而不是我们一般所说的时间片轮转的那种并发。例如,多核系统中,返回值可以是CPU核芯的数量。
1 #include <iostream> 2 #include <thread> 3 #include <vector> 4 5 using namespace std; 6 7 void func(int i) 8 { 9 cout << "子线程func" << i << "开始执行!" << endl; 10 //do something 11 //方法二 12 cout << "func线程" << i << "的id: " << this_thread::get_id() << endl; 13 cout << "子线程func" << i << "执行结束!" << endl; 14 } 15 16 int main() 17 { 18 cout << "主线程main开始执行!" << endl; 19 cout << "main线程的id: " << this_thread::get_id() << endl; 20 vector<thread> thdvec; 21 int n; 22 cin >> n; 23 //运行时确定线程数量 24 for (int i = 0; i < n; ++i) 25 thdvec.push_back(thread(func, i)); 26 27 for (auto iter = thdvec.begin(); iter != thdvec.end(); ++iter) 28 iter->join(); 29 cout << "主线程main执行结束!" << endl; 30 return 0; 31 }
获取线程id
线程标识类型是 std::thread::id 类型。有两种获取id的方法。
方法一:可以通过调用 std::thread 对象的成员函数 get_id() 来获取id。
方法二:在当前线程中使用std::this_thread::get_id()来获取线程id。
1 #include <thread> 2 #include <iostream> 3 4 using namespace std; 5 6 void func() 7 { 8 cout << "子线程func开始执行!" << endl; 9 //do something 10 //方法二 11 cout << "func线程的id: " << this_thread::get_id() << endl; 12 cout << "子线程func执行结束!" << endl; 13 } 14 15 int main() 16 { 17 18 cout << "主线程main开始执行!" << endl; 19 cout << "main线程的id: " << this_thread::get_id() << endl; 20 thread t(func); 21 //方法一 22 cout << "在main线程中获取func线程id:" << t.get_id() << endl; 23 t.join(); 24 cout << "主线程main执行结束!" << endl; 25 return 0; 26 }
菜鸟手记。