std::thread

头文件

#include<thread> 头文件中声明

命名空间统一在std

 
成员类型和成员函数

成员类型:

id
native_handle_type

成员函数:
Construct thread // 构造函数
Thread destructor // 析构函数
operator=// 赋值重载
get_id // 获取线程id
joinable// 判断线程是否可以加入等待
join//Join thread (public member function ) 加入等待
detach//Detach thread (public member function ) 分离线程
swap//Swap threads (public member function ) 线程交换
native_handle// 获取线程句柄
hardware_concurrency // 检测硬件并发特性
swap (thread)
Swap threads (function )

 

std::thread 构造函数  #include<thread> 

 #include<chrono>
 using namespace std;
 void fun1(int n) //初始化构造函数
 {
     cout << "Thread " << n << " executing\n";
     n += 10;
     this_thread::sleep_for(chrono::milliseconds(10));
 }
 void fun2(int & n) //拷贝构造函数
 {
     cout << "Thread " << n << " executing\n";
     n += 20;
     this_thread::sleep_for(chrono::milliseconds(10));
 }
 int main()
 {
     int n = 0;
     thread t1; //t1不是一个thread
     thread t2(fun1, n + 1); //按照值传递
     t2.join();
     cout << "n=" << n << '\n';
     n = 10;
     thread t3(fun2, ref(n)); //引用
     thread t4(move(t3)); //t4执行t3,t3不是thread
     t4.join();
     cout << "n=" << n << '\n';
     return 0;
 }
 运行结果:
 Thread 1 executing
 n=0
 Thread 10 executing
 n=30

 

同、异步

CPP原子变量与线程安全

 

 多线程资源竞争问题例如:

 #include<iostream>
 #include<thread>
 using namespace std;
 const int N = 100000000;
 int num = 0;
 void run()
 {
     for (int i = 0; i < N; i++)
     {
         num++;
     }
 }
 int main()
 {
     clock_t start = clock();
     thread t1(run);
     thread t2(run);
     t1.join();
     t2.join();
     clock_t end = clock();
     cout << "num=" << num << ",用时 " << end - start << " ms" << endl;
     return 0;
 }
 运行结果:
 num=143653419,用时 730 ms</span>
从上述代码执行的结果,发现结果并不是我们预计的200000000,这是由于线程之间发生冲突,从而导致结果不正确。
为了解决此问题,有以下方法:
(1)互斥量。
例如:

 #include<iostream>
 #include<thread>
 #include<mutex>
 using namespace std;
 const int N = 100000000;
 int num(0);
 mutex m;
 void run()
 {
     for (int i = 0; i < N; i++)
     {
         m.lock();
         num++;
         m.unlock();
     }
 }
 int main()
 {
     clock_t start = clock();
     thread t1(run);
     thread t2(run);
     t1.join();
     t2.join();
     clock_t end = clock();
     cout << "num=" << num << ",用时 " << end - start << " ms" << endl;
     return 0;
 }
 运行结果:
 num=200000000,用时 128323 ms</span>
通过互斥量后运算结果正确,但是计算速度很慢,原因主要是互斥量加解锁需要时间。
互斥量详细内容 请参考C++11 并发之std::mutex。(2)原子变量。


 #include<iostream>
 #include<thread>
 #include<atomic>
 using namespace std;
 const int N = 100000000;
 atomic_int num{ 0 };//不会发生线程冲突,线程安全
 void run()
 {
     for (int i = 0; i < N; i++)
     {
         num++;
     }
 }
 int main()
 {
     clock_t start = clock();
     thread t1(run);
     thread t2(run);
     t1.join();
     t2.join();
     clock_t end = clock();
     cout << "num=" << num << ",用时 " << end - start << " ms" << endl;
     return 0;
 }
 运行结果:
 num=200000000,用时 29732 ms</span>
通过原子变量后运算结果正确,计算速度一般。
原子变量详细内容 请参考C++11 并发之std::atomic。

 

#include<iostream>
#include<thread>
#include<chrono>
using namespace std;
int main()
 {
     thread th1([]()
     {
         //让线程等待3秒
         this_thread::sleep_for(chrono::seconds(3));
         //让cpu执行其他空闲的线程
         this_thread::yield();
         //线程id
         cout << this_thread::get_id() << endl;
     });
     return 0;
 }

 
多线程传递参数   #include<iostream> 

 #include<thread>
 using namespace std;
 void show(const char *str, const int id)
 {
     cout << "线程 " << id + 1 << " :" << str << endl;
 }
 int main()
 {
     thread t1(show, "hello cplusplus!", 0);
     thread t2(show, "你好,C++!", 1);
     thread t3(show, "hello!", 2);
     return 0;
 }
 运行结果:
线程 1: hello!

线程 2:你好,

线程 3 : hello cplusplus! 

发现,线程 t1、t2、t3 都执行成功!

 
join、detach   #include<iostream> 

 #include<thread>
 #include<array>
 using namespace std;
 void show()
 {
     cout << "hello cplusplus!" << endl;
 }
 int main()
 {
     array<thread, 3> threads = { thread(show), thread(show), thread(show) };
     for (int i = 0; i < 3; i++)  {
         cout << threads[i].joinable() << endl;//判断线程是否可以join
         threads[i].join();//主线程等待当前线程执行完成再退出
     }
     return 0;
 }
 运行结果:
 hello cplusplus!
 hello cplusplus!
 1
 hello cplusplus!
 1
 1 
总结:
join 是让当前主线程等待所有的子线程执行完,才能退出。

detach如下:

 #include<iostream>
 #include<thread>
 using namespace std;
 void show()
 {
     cout << "hello cplusplus!" << endl;
 }
 int main()
 {
     thread th(show);
     //th.join();
     th.detach();//脱离主线程的绑定,主线程挂了,子线程不报错,子线程执行完自动退出。
     //detach以后,子线程会成为孤儿线程,线程之间将无法通信。
     cout << th.joinable() << endl;
     return 0;
 }
 运行结果:
 hello cplusplus!
 0
结论:
线程 detach 脱离主线程绑定,主线程退出,子线程不报错,子线程执行完自动退出。
线程 detach以后,子线程会成为孤儿线程,线程之间将无法通信或被同步。

 
lambda与多线程  #include<iostream> 

 #include<thread>
 using namespace std;
 int main()
 {
     auto fun = [](const char *str) {cout << str << endl; };
     thread t1(fun, "hello world!");
     thread t2(fun, "hello beijing!");
     return 0;
 }

 
线程交换

 #include <iostream> 

#include<thread> 

 using namespace std;
 int main()
 {
     thread t1([]() {
         cout << "thread1" << endl;
     });
     thread t2([]()  {
         cout << "thread2" << endl;
     });
     cout << "thread1' id is " << t1.get_id() << endl;
     cout << "thread2' id is " << t2.get_id() << endl;

     cout << "swap after:" << endl;
     swap(t1, t2);//线程交换
     cout << "thread1' id is " << t1.get_id() << endl;
     cout << "thread2' id is " << t2.get_id() << endl;
     return 0;
 }
 运行结果:
 thread1
 thread2
 thread1' id is 4836
 thread2' id is 4724
 swap after:
 thread1' id is 4724
 thread2' id is 4836
两个线程通过 swap 进行交换。

 
线程移动  #include<iostream> 

 #include<thread>
 using namespace std;
 int main()
 {
     thread t1([]() {
         cout << "thread1" << endl;
     });
     cout << "thread1' id is " << t1.get_id() << endl;
     thread t2 = move(t1);;
     cout << "thread2' id is " << t2.get_id() << endl;
     return 0;
 }

 
多线程可变参数  #include<iostream> 

 #include<thread>
 #include<cstdarg>
 using namespace std;
 int show(const char *fun, ...)
 {
     va_list ap;//指针
     va_start(ap, fun);//开始
     vprintf(fun, ap);//调用
     va_end(ap);
     return 0;
 }
 int main()
 {
     thread t1(show, "%s %d %c %f", "hello world!", 100, 'A', 3.14159);
     return 0;
 }
 运行结果:
 hello world! 100 A 3.14159</span>

 
线程类扩展

#include<iostream>
#include<thread>
 using namespace std;
 class MyThread :public thread //继承thread
 {
 public:
     MyThread() : thread()
     {
     }
     //MyThread()初始化构造函数
     template<typename T, typename...Args>
     MyThread(T&&func, Args&&...args) : thread(forward<T>(func), forward<Args>(args)...)
     {
     }
     void showcmd(const char *str) {
         system(str); //运行system 
     }
 };
 int main()
 {
     MyThread th1([]() {
         cout << "hello" << endl;
     });
     th1.showcmd("calc"); //运行calc
     //lambda
     MyThread th2([](const char * str)  {
         cout << "hello" << str << endl;
     }, " this is MyThread");
     th2.showcmd("notepad");//运行notepad
     return 0;
 }
 运行结果:
 hello
 //运行calc
 hello this is MyThread
 //运行notepad

 

this_thread

命名空间

thread的所有辅助函数位于std::this_thread命名空间中:

namespace this_thread

{

   thread::id get_id()  _NOEXCEPT;

   inline void yield()  _NOEXCEPT;

   template<class_Rep, class_Period> inline 

   void sleep_for(const chrono::duration<_Rep,_Period>&_Rel_time)

  template<class_Clock,class_Duration>inline

  void sleep_until(const chrono::time_point<_Clock,_Duration>&_Abs_time)

}

 

posted @ 2019-06-20 09:49  Reboost  阅读(273)  评论(0)    收藏  举报