c++11 新特性实战 (一):多线程操作
c++11多线程操作
- 线程 - thread
 - int main()
 {
 thread t1(Test1);
 t1.join();
 thread t2(Test2);
 t2.join();
 thread t3 = t1;
 thread t4(t1);
 thread t5 = std::move(t1);
 thread t6(std::move(t1));
 return 0;
 }
 - t3,t4创建失败,因为thread的拷贝构造和赋值运算符重载的原型是: - thread(const thread&) = delete;
 thread& operator=(const thread&) = delete;
 - 被禁用了,但是t5, t6线程是创建成功的。std::move把t1转换为右值,调用的是函数原型为 - thread& operator=(thread&& _Other) noexcept和- thread(thread&& _Other) noexcept。- 当线程对象t1被移动拷贝和移动赋值给t5和t6的时候,t1就失去了线程控制权,也就是一个线程只能同时被一个线程对象所控制。最直观的是t1.joinable()返回值为false,joinable()函数后面介绍。 - 使用类成员函数作为线程参数: - class Task
 {
 public:
 Task(){}
 void Task1() {}
 void Task2() {}
 private:
 }; int main()
 {
 Task task;
 thread t3(&Task::Task1, &task);
 t3.join();
 return 0;
 }
 - 关键点是要创建一个类对象,并作为第二个参数传入 - thread()线程的构造函数中去。
- 管理当前线程的函数 - yield
 - 此函数的准确性为依赖于实现,特别是使用中的 OS 调度器机制和系统状态。例如,先进先出实时调度器( Linux 的 - SCHED_FIFO)将悬挂当前线程并将它放到准备运行的同优先级线程的队列尾(而若无其他线程在同优先级,则- yield无效果)。- #include <iostream>
 #include <chrono>
 #include <thread> // 建议其他线程运行一小段时间的“忙睡眠”
 void little_sleep(std::chrono::microseconds us)
 {
 auto start = std::chrono::high_resolution_clock::now();
 auto end = start + us;
 do {
 std::this_thread::yield();
 } while (std::chrono::high_resolution_clock::now() < end);
 } int main()
 {
 auto start = std::chrono::high_resolution_clock::now(); little_sleep(std::chrono::microseconds(100)); auto elapsed = std::chrono::high_resolution_clock::now() - start;
 std::cout << "waited for "
 << std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count()
 << " microseconds\n";
 }
 - get_id
 - 这个函数不用过多介绍了,就是用来获取当前线程id的,用来标识线程的身份。 - std::thread::id this_id = std::this_thread::get_id();
 - sleep_for
 - 位于this_thread命名空间下,msvc下支持两种时间参数。 - std::this_thread::sleep_for(2s);
 std::this_thread::sleep_for(std::chrono::seconds(1));
 - sleep_untile
 - 参数构建起来挺麻烦的,一般场景下要求线程睡眠的就用sleep_for就行了 - using std::chrono::system_clock;
 time_t tt = system_clock::to_time_t(system_clock::now());
 struct std::tm *ptm = localtime(&tt);
 std::this_thread::sleep_until(system_clock::from_time_t(mktime(ptm)));
 
- 互斥 - mutex
 - 对于互斥量看到一个很好的比喻: - 单位上有一台打印机(共享数据a),你要用打印机(线程1要操作数据a),同事老王也要用打印机(线程2也要操作数据a),但是打印机同一时间只能给一个人用,此时,规定不管是谁,在用打印机之前都要向领导申请许可证(lock),用完后再向领导归还许可证(unlock),许可证总共只有一个,没有许可证的人就等着在用打印机的同事用完后才能申请许可证(阻塞,线程1lock互斥量后其他线程就无法lock,只能等线程1unlock后,其他线程才能lock),那么,这个许可证就是互斥量。互斥量保证了使用打印机这一过程不被打断。 - 代码示例: - mutex mtx; int gNum = 0;
 void Test1()
 {
 mtx.lock();
 for(int n = 0; n < 5; ++n)
 gNum++;
 mtx.unlock();
 } void Test2()
 {
 std::cout << "gNum = " << gNum << std::endl;
 } int main()
 {
 thread t1(Test1);
 t1.join();
 thread t2(Test2);
 t2.join();
 return 0;
 }- join()表示主线程等待子线程结束再继续执行,如果我们的期望是打印循环自增之后的gNum的值,那t1.join()就放在t2创建之前调用。因为t2的创建就标志着t2线程创建好然后开始执行了。 - 通常mutex不单独使用,因为lock和unlock必须配套使用,如果忘记unlock很可能造成死锁,即使unlock写了,但是如果在执行之前程序捕获到异常,也还是一样会死锁。如何解决使用mutex造成的死锁问题呢?下面介绍unique_gard和lock_guard的时候详细说明。 - timed_mutex
 - 提供互斥设施,实现有时限锁定 - recursive_mutex
 - 提供能被同一线程递归锁定的互斥设施 - recursive_timed_mutex
 - 提供能被同一线程递归锁定的互斥设施,并实现有时限锁定 
- 通用互斥管理 - lock_guard
 - void Test1()
 {
 std::lock_guard<std::mutex> lg(mtx);
 for(int n = 0; n < 5; ++n)
 {
 gNum++;
 std::cout << "gNum = " << gNum << std::endl;
 }
 }
 int main()
 {
 thread t1(Test1);
 thread t2(Test1);
 t1.join();
 t2.join();
 return 0;
 }
 - lock_guard相当于利用RAII机制(“资源获取就是初始化”)把mutex封装了一下,在构造中lock,在析构中unlock。避免了中间过程出现异常导致的mutex不能够正常unlock. - scoped_lock(c++17)
- unique_lock
- defer_lock_t
- try_to_lock_t
- adopt_lock_t
- defer_lock
- try_to_lock
- adopt_lock
 
- 通用锁算法 - try_lock
- lock
 
- 单次调用 - once_flag
- call_once
 
- 条件变量 - condition_variable
- condition_variable_any
- notify_all_at_thread_exit
- cv_status
 
- Future - promise
- packaged_task
- future
- shared_future
- async
- launch
- future_status
- Future错误
- future_error
- future_category
- future_errc
 
 
c++11 新特性实战 (一):多线程操作的更多相关文章
- c++11新特性实战(二):智能指针
		c++11添加了新的智能指针,unique_ptr.shared_ptr和weak_ptr,同时也将auto_ptr置为废弃(deprecated). 但是在实际的使用过程中,很多人都会有这样的问题: ... 
- [转载] C++11新特性
		C++11标准发布已有一段时间了, 维基百科上有对C++11新标准的变化和C++11新特性介绍的文章. 我是一名C++程序员,非常想了解一下C++11. 英文版的维基百科看起来非常费劲,而中文版维基百 ... 
- c++学习书籍推荐《深入理解C++11 C++11新特性解析与应用》下载
		百度云及其他网盘下载地址:点我 编辑推荐 <深入理解C++11:C++11新特性解析与应用>编辑推荐:C++标准委员会成员和IBM XL编译器中国开发团队共同撰写,权威性毋庸置疑.系统.深 ... 
- c++ 11 线程池---完全使用c++ 11新特性
		前言: 目前网上的c++线程池资源多是使用老版本或者使用系统接口实现,使用c++ 11新特性的不多,最近研究了一下,实现一个简单版本,可实现任意任意参数函数的调用以及获得返回值. 0 前置知识 首先介 ... 
- C++11新特性总结 (二)
		1. 范围for语句 C++11 引入了一种更为简单的for语句,这种for语句可以很方便的遍历容器或其他序列的所有元素 vector<int> vec = {1,2,3,4,5,6}; ... 
- C++11新特性总结 (一)
		1. 概述 最近在看C++ Primer5 刚好看到一半,总结一下C++11里面确实加了很多新东西,如果没有任何了解,别说自己写了,看别人写的代码估计都会有些吃力.C++ Primer5是学习C++1 ... 
- 在C++98基础上学习C++11新特性
		自己一直用的是C++98规范来编程,对于C++11只闻其名却没用过其特性.近期因为工作的需要,需要掌握C++11的一些特性,所以查阅了一些C++11资料.因为自己有C++98的基础,所以从C++98过 ... 
- C++11新特性——range for
		很多编程语言都有range for语法功能,自C++11起,终于将这个重要功能加入C++标准中.range for语句,可以方便的遍历给定序列中的每个元素并对其执行某种操作. 1.基本语法 for(d ... 
- C++11 新特性之智能指针(shared_ptr, unique_ptr, weak_ptr)
		这是C++11新特性介绍的第五部分,涉及到智能指针的相关内容(shared_ptr, unique_ptr, weak_ptr). shared_ptr shared_ptr 基本用法 shared_ ... 
随机推荐
- Leetcode 24. Swap Nodes in Pairs(详细图解一看就会)
			题目内容 Given a linked list, swap every two adjacent nodes and return its head. You may not modify the ... 
- .NET ORM 导航属性【到底】可以解决什么问题?
			写在开头 从最早期入门时的单表操作, 到后来接触了 left join.right join.inner join 查询, 因为经费有限,需要不断在多表查询中折腾解决实际需求,不知道是否有过这样的经历 ... 
- 码云git clone报错Incorrect username or password ( access token )
			使用码云将仓库clone到本地,报错信息如下: D:\>git clone https://gitee.com/ycyzharry/helloworld.git Cloning into 'he ... 
- e3mall商城的归纳总结7之solr搭建和应用
			敬给读者的话 本文主要应用的技术是solr技术的搭建和应用,本文小编尽量写的更详细一些,让读者在不考虑项目的情况下也能正常完成solr的搭建,说完搭建之后,再说明运行solrj在项目中如何应用solr ... 
- 复制一个Python全部环境到另一个环境
			导出此环境下安装的包的版本信息清单 pip freeze > requirements.txt 联网,下载清单中的包到all-packet文件夹 [root@localhost ~]# p ... 
- Android开发之第三方推送JPush极光推送知识点详解 学会集成第三方SDK推送
			作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 下面是一些知识点介绍,后期将会带领大家进行代码实战: 一.Android实现推送方式解决方案: 1.推 ... 
- iview table  render 进阶(一)
			Qestion: 如何给表格添加hover 事件? step1: 添加 domProps 选项参数 step2: 废话不多说,直接看demo code render: (h, params) =& ... 
- P1004 方格取数(四维动态规划)
			题目描述 设有N \times NN×N的方格图(N \le 9)(N≤9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字00.如下图所示(见样例): A 0 0 0 0 0 0 0 0 ... 
- House of Orange
			题目附件:https://github.com/ctfs/write-ups-2016/tree/master/hitcon-ctf-2016/pwn/house-of-orange-500 查看程序 ... 
- 零基础一分钟入门Python
			这篇文章面向所有想学python的小伙伴(甚至你从没听过编程),这篇文章将会带你以最快的速度入门python.赶快上车,时间来不及了... 一,下载和安装python 1.下载: 1.1 python ... 
