建设网站的提成是多少,网页空间层次,做微信推送用什么网站,中国企业100强C11并发之std::thread知识链接#xff1a;C11 并发之std::mutexC11 并发之std::atomic本文概要#xff1a;1、成员类型和成员函数。2、std::thread 构造函数。3、异步。4、多线程传递参数。5、join、detach。6、获取CPU核心个数。7、CPP原子变量与线程安全。8、lambda与多线程…C11并发之std::thread 知识链接 C11 并发之std::mutex C11 并发之std::atomic 本文概要 1、成员类型和成员函数。 2、std::thread 构造函数。 3、异步。 4、多线程传递参数。 5、join、detach。 6、获取CPU核心个数。 7、CPP原子变量与线程安全。 8、lambda与多线程。 9、时间等待相关问题。 10、线程功能拓展。 11、多线程可变参数。 12、线程交换。 13、线程移动。 std::thread 在 #includethread 头文件中声明因此使用 std::thread 时需要包含 #includethread 头文件。 1、成员类型和成员函数。 成员类型 idThread id (public member type ) idnative_handle_typeNative handle type (public member type )成员函数 (constructor)Construct thread (public member function ) 构造函数(destructor)Thread destructor (public member function ) 析构函数operatorMove-assign thread (public member function ) 赋值重载get_idGet thread id (public member function ) 获取线程idjoinableCheck if joinable (public member function ) 判断线程是否可以加入等待joinJoin thread (public member function ) 加入等待detachDetach thread (public member function ) 分离线程swapSwap threads (public member function ) 线程交换native_handleGet native handle (public member function ) 获取线程句柄hardware_concurrency [static]Detect hardware concurrency (public static member function ) 检测硬件并发特性Non-member overloads swap (thread)Swap threads (function ) 2、std::thread 构造函数。 如下表 default (1)thread() noexcept;initialization(2)template class Fn, class... Args explicit thread (Fn fn, Args... args);copy [deleted] (3)thread (const thread) delete;move [4]hread (thread x) noexcept; (1).默认构造函数创建一个空的 thread 执行对象。 (2).初始化构造函数创建一个 thread 对象该 thread 对象可被 joinable新产生的线程会调用 fn 函数该函数的参数由 args 给出。 (3).拷贝构造函数被禁用意味着 thread 不可被拷贝构造。 (4).move 构造函数move 构造函数调用成功之后 x 不代表任何 thread 执行对象。 注意可被 joinable 的 thread 对象必须在他们销毁之前被主线程 join 或者将其设置为 detached。 std::thread 各种构造函数例子如下 [cpp] view plain copy span stylefont-size:12px;#includeiostream #includethread #includechrono 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执行t3t3不是thread t4.join(); cout n n \n; return 0; } 运行结果: Thread 1 executing n0 Thread 10 executing n30/span 3、异步。 例如 [cpp] view plain copy span stylefont-size:12px;#includeiostream #includethread using namespace std; void show() { cout hello cplusplus! endl; } int main() { //栈上 thread t1(show); //根据函数初始化执行 thread t2(show); thread t3(show); //线程数组 thread th[3]{thread(show), thread(show), thread(show)}; //堆上 thread *pt1(new thread(show)); thread *pt2(new thread(show)); thread *pt3(new thread(show)); //线程指针数组 thread *pth(new thread[3]{thread(show), thread(show), thread(show)}); return 0; }/span 4、多线程传递参数。 例如 [cpp] view plain copy span stylefont-size:12px;#includeiostream #includethread 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线程 2 你好C线程 3 hello! hello cplusplus!/span 发现线程 t1、t2、t3 都执行成功 5、join、detach。 join例子如下 [cpp] view plain copy span stylefont-size:12px;#includeiostream #includethread #includearray using namespace std; void show() { cout hello cplusplus! endl; } int main() { arraythread, 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/span 总结 join 是让当前主线程等待所有的子线程执行完才能退出。 detach例子如下 [cpp] view plain copy span stylefont-size:12px;#includeiostream #includethread 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/span 结论 线程 detach 脱离主线程的绑定主线程挂了子线程不报错子线程执行完自动退出。 线程 detach以后子线程会成为孤儿线程线程之间将无法通信。 6、获取CPU核心个数。 例如 [cpp] view plain copy span stylefont-size:12px;#includeiostream #includethread using namespace std; int main() { auto n thread::hardware_concurrency();//获取cpu核心个数 cout n endl; return 0; } 运行结果: 8/span 结论 通过 thread::hardware_concurrency() 获取 CPU 核心的个数。 7、CPP原子变量与线程安全。 问题例如 [cpp] view plain copy span stylefont-size:12px;#includeiostream #includethread 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; } 运行结果: num143653419,用时 730 ms/span 从上述代码执行的结果发现结果并不是我们预计的200000000这是由于线程之间发生冲突从而导致结果不正确。 为了解决此问题有以下方法 1互斥量。 例如 [cpp] view plain copy span stylefont-size:12px;#includeiostream #includethread #includemutex 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; } 运行结果 num200000000,用时 128323 ms/span 不难发现通过互斥量后运算结果正确但是计算速度很慢原因主要是互斥量加解锁需要时间。 互斥量详细内容 请参考C11 并发之std::mutex。 2原子变量。 例如 [cpp] view plain copy span stylefont-size:12px;#includeiostream #includethread #includeatomic 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; } 运行结果: num200000000,用时 29732 ms/span 不难发现通过原子变量后运算结果正确计算速度一般。 原子变量详细内容 请参考C11 并发之std::atomic。 3加入 join 。 例如 [cpp] view plain copy span stylefont-size:12px;#includeiostream #includethread 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); t1.join(); thread t2(run); t2.join(); clock_t end clock(); cout num num ,用时 end - start ms endl; return 0; } 运行结果 num200000000,用时 626 ms/span 不难发现通过原子变量后运算结果正确计算速度也很理想。 8、lambda与多线程。 例如 [cpp] view plain copy span stylefont-size:12px;#includeiostream #includethread 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; } 运行结果 hello world! hello beijing!/span 9、时间等待相关问题。 例如 [cpp] view plain copy span stylefont-size:12px;#includeiostream #includethread #includechrono 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; }/span 10、线程功能拓展。 例如 [cpp] view plain copy span stylefont-size:12px;#includeiostream #includethread using namespace std; class MyThread :public thread //继承thread { public: //子类MyThread()继承thread()的构造函数 MyThread() : thread() { } //MyThread()初始化构造函数 templatetypename T, typename...Args MyThread(Tfunc, Args...args) : thread(forwardT(func), forwardArgs(args)...) { } void showcmd(const char *str) //运行system { system(str); } }; 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/span 11、多线程可变参数。 例如 [cpp] view plain copy span stylefont-size:12px;#includeiostream #includethread #includecstdarg 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 12、线程交换。 例如 [cpp] view plain copy span stylefont-size:12px;#includeiostream #includethread 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/span 两个线程通过 swap 进行交换。 13、线程移动。 例如 [cpp] view plain copy span stylefont-size:12px;#includeiostream #includethread 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; } 运行结果: thread1 thread1 id is 5620 thread2 id is 5620/span 从上述代码中线程t2可以通过 move 移动 t1 来获取 t1 的全部属性而 t1 却销毁了。 转载于:https://www.cnblogs.com/mmc9527/p/10427924.html