Moderns C++
lesliefish
不要停歇、不回头
展开
-
现代C ++中的多线程
前言随着新的C ++ 11标准发布,C ++首次面临多核架构的挑战。 2011年发布的标准定义了C ++程序在存在多个线程时的行为方式。 C ++ 11多线程功能由两个组件组成:一方面是内存模型的定义,另一方面是标准化的线程接口。 下面是C++进化图: 一个定义明确的内存模型一个定义明确的内存模型是基础,以此确保在C ++中多线程编程是有意义的。因此,内存模型上必须给出...翻译 2018-07-09 23:11:06 · 2463 阅读 · 0 评论 -
C++11 Tasks 线程与任务的区别
tasks是最新额外添加的C++标准。 这是给了一个比线程更好的抽象。 通常情况下,这应该是你的第一选择。Tasks行为就像是数据通道。 一方面,发送者设置一个值。 另一方面,接收者获取这个值。 发送这人通常被称为promise, 接收者被称为future. 或者换句话说就是, 发送者承诺提供一个值, 接收者在将来可以获取到它。 来看一些更多的细节。发送者可以提...翻译 2018-09-02 18:28:37 · 4903 阅读 · 0 评论 -
C++异步callable包装器 std::packaged_task
std::packaged_taskstd::packaged_task使得你可以对callable写一个简单的包装器,稍候再调用。(译者:类似线程池啊) 想要用好std::packaged_task,你必须处理好这四个步骤:1、包装task2、创建future3、执行计算4、获取结果简单程序示例一下上面的步骤:// packagedTask.cpp#inc...翻译 2018-09-04 21:29:06 · 491 阅读 · 0 评论 -
C++异步调用 std::async
std::asyncEager or lazy evaluation(急速或惰性求值)一个规模大的计算任务std::async 就像是一个异步函数调用。 std::async 之下呢是一个task,非常好用的task。std::asyncstd::async 使用一个 callable 作为一个工作包。 在本例中,它可以是个函数、函数对象或者匿名函数。...翻译 2018-09-04 13:03:25 · 20354 阅读 · 1 评论 -
C++条件变量--std::condition_variable
条件变量允许我们通过通知进而实现线程同步。 因此,您可以实现发送方/接收方或生产者/消费者之类的工作流。 在这样的工作流程中,接收者正在等待发送者的通知。如果接收者收到通知,它将继续工作。std::condition_variable条件变量可以履行发送者或接收者的角色。 作为发送者,它可以通知一个或多个接收者。 这就是使用条件变量所需要知道的基本所有内容,程序示例:/...翻译 2018-07-29 16:59:39 · 21920 阅读 · 1 评论 -
C++线程本地数据--thread_local类型数据
通过使用关键字thread_local,可以定义线程本地数据。thread_local在必要的情况下,我们可以为每个线程创建线程本地数据。 线程局部数据专属于线程,其行为类似于静态数据。 这意味着,它将在第一次使用时创建,其生命周期将绑定到线程的生命周期。 线程本地数据通常称为线程本地存储。 使用线程本地数据非常简单,下面是个小程序:// threadLocal.c...翻译 2018-07-29 15:10:54 · 8674 阅读 · 0 评论 -
C++锁的管理-- std::lock_guard和std::unique_lock
前言锁管理遵循RAII习语来处理资源。锁在构造函数中自动绑定它的互斥体,并在析构函数中释放它。这大大减少了死锁的风险,因为运行时会处理互斥体。。 锁在C++ 11中有两种: 用于简单的std::lock_guard,以及用于高级用例的std::unique_lock。std::lock_guard先来个小例子吧:mutex m;m.lock();sharedVari...翻译 2018-07-13 00:31:55 · 35553 阅读 · 3 评论 -
C++线程--互斥锁的风险
前言互斥锁的使用似乎非常简单。 只要保证代码中的关键部分,只能在任何时间点由单个线程访问就行了。一个互斥锁变量mt通过调用m.lock()和m.unlock()就保证了这种排他性。但是,魔鬼在于细节。。。死锁死锁的不同名字很可怕。有人称之为致命拥抱?或者死亡之吻。 但是等等,什么是死锁? 死锁是一种状态,其中至少有两个线程被阻塞,因为每个线程都在等待释放其他线程工作的某些资源...翻译 2018-07-11 23:09:38 · 851 阅读 · 0 评论 -
C++线程的创建
前言线程创建很容易,直接调用std::thread,就创建一个新线程了。该线程拿到任务后立即开始执行。 线程的创建者(父线程)必须管理创建的线程(子线程),应该等到子线程完成其任务或者让子线程从自己身上脱离。子线程可以通过复制或引用获取任务执行的参数。创建和执行线程现在,更正式的方法创建线程:一个线程获得一个Callable后立即启动它。Callable是一个行为类似于一...翻译 2018-07-11 22:34:19 · 22260 阅读 · 5 评论 -
C++线程的参数传递:值传递和引用
前言线程一般通过复制或引用获取其数据。 默认情况下,您应该用一个副本。 为啥呢?如果您的线程通过引用获取其数据,那得非常小心参数的生命周期。线程参数线程是可变参数模板。所以它可以获得任意数量的参数。 现在咱们来看看通过复制或引用获取参数之间的区别: std::string s{ "C++11" } std::thread t([=] { ...翻译 2018-07-11 09:20:49 · 5762 阅读 · 0 评论 -
C++线程间共享数据之互斥锁
当线程间共享非const类型的数据时,线程管理的最大挑战之一就开始了。。 使用共享数据的线程的上下文中,您经常会听到竞争条件和竞争区。 但是,那是啥?数据竞争数据竞争是一种状态,其中至少两个线程同时访问共享数据,并且至少一个线程是写入者。竞争区竞争区是代码的一部分,在任何时间点都不应该有多个线程访问。 如果程序具有竞争条件,则程序行为未定义。换句话说,任何事情都可能发生。...翻译 2018-07-10 23:41:13 · 3406 阅读 · 0 评论 -
C++11线程的生命周期
前言父母必须照管好孩子。线程也一样,父线程对子线程生命周期有很大的影响。 以下程序启动一个显示其ID的线程。// threadForgetJoin.cpp#include <iostream>#include <thread>int main(){ std::thread t([] { std::cout <&...翻译 2018-07-10 00:29:54 · 4566 阅读 · 0 评论 -
C++ promise和future
通过使用 std::promise 和 std::future,就有了task的全部控制权。std::promise 允许设置一个值,一个消息,或者一个异常。 该结果可以延迟由promise提供。std::future 可以从promise获取值,请求性获取,值可用的话就可获取到了。 等待promise的消息通知。 等待可以使用一个相对持续时间或绝对时间点来完成=>替代...翻译 2018-09-06 13:53:48 · 4097 阅读 · 0 评论