自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

t114211200的博客

C++11 多线程 STL

  • 博客(50)
  • 资源 (5)
  • 收藏
  • 关注

原创 《数据结构与算法分析》笔记5 AVL树

AVL树:带有平衡条件的二叉树。是每个节点的左右子树的高度最多差1的二叉查找树。为了使其保持平衡,需要在插入或删除节点时做单旋转或双旋转。假设,在插入或删除操作之后,节点a已经变得不平衡,那么如果导致不平衡的动作是:对a的左儿子的左子树进行一次插入,或者是,对a的右儿子的右子树进行一次插入,则需要进行一次单旋转;对a的左儿子的右子树进行一次插入,或者是,对a的右儿子的左子树进行一次插入,则需要进行...

2018-04-10 22:35:44 303

原创 《数据结构与算法分析》笔记4 二叉查找树

二叉树:任意节点最多有2个子节点的树。二叉查找树:对于任意节点X,它的左子树中的所有关键字的值(节点中存的值)小于X的关键字的值,而它的右子树中的所有关键字值都大于X的关键字的值。二叉查找树的平均深度为O(logN)。insert:从根节点依次查找所要插入节点的正确位置。delete:使用被删除节点的右子树中最小的节点代替该节点,递归实现这一过程。二叉查找树的基本操作的平均运行时间都是O(logN...

2018-03-25 17:39:12 211

原创 《数据结构与算法分析》笔记3 树的基本概念

树是节点的集合,这集合可以为空;若非空,则一棵树由根节点r以及0个或多个非空的(子)树组成,这些子树中欧每一颗的根都被来自根r的一条有向的边所连接。树叶是没有子节点的节点。节点的深度是从根到该节点唯一路径的长。根节点的深度为0。节点的高是从该节点到一片树叶的最长路径的长。任意树叶的高为0。树的高等于它最深的树叶的深度。...

2018-03-25 17:27:32 234

原创 《数据结构与算法分析》笔记2 运行时间中的对数

这里说的对数都是指以2为底的对数。如果一个算法用常数时间将问题的大小消减为原来的1/2,则这个算法就是O(logN)的。常见的O(logN)算法举例:对分查找、欧几里得算法、幂运算。欧几里得求两个数的最大公因数unsigned int Gcd(unsigned int M, unsigned int N){    using int Rem;    while(N>0)    {      ...

2018-03-25 16:57:26 241

原创 《数据结构与算法分析》笔记1 准备知识

最近在看Mark Allen Weiss的《数据结构与算法分析》C语言描述版本,为了以后复习,将概要信息记录下来。多项式和:1+2+3+4+5+...+n=n(1+n)/2定义:如果存在正常数c和n0使得当N>=n0时T(N)<=cf(N),则记为T(N) = O(f(N))。(代表T(N)的增长率<=f(N)的增长率)定义:如果存在正常数c和n0使得当N>=n0时T(N)...

2018-03-25 16:46:59 284

原创 《C++ Concurrency in Action》笔记31 测试及调试多线程应用程序

10 测试及调试并行应用在设计并行代码时要

2017-10-22 22:52:58 385

原创 《C++ Concurrency in Action》笔记30 高级线程管理——线程池及中断线程

9 高级线程管理在之前的章节,我们通过直接创建std::thread对象来管理线程。有几处你已经看出,这是不可取的,因为之后你必须管理线程对象的生命期,以及确定适合该问题的线程数和当前的硬件,等等。理想的情况是,你可以最大程度的将代码分成可以并行执行的小块,把它们交给编译器和标准库,然后说:“把它们并行化以获得最佳性能”。这些例子中的另一个常见问题就是,你可能使用了多个线程来解决一个问

2017-10-20 17:51:26 1368 1

原创 《C++ Concurrency in Action》笔记29 设计并行代码(2)

8.4.2 可伸缩性与阿姆达尔定律(Amdahl’s law)可伸缩性是关于确保你的代码可以利用所运行系统上的附新增的处理器。极端情况是,一个单线程应用完全是不可伸缩的;即使为系统增加100个处理器,它的效率也不会改变。另一个极端情况是,你有一个类似于SETI@Home工程的应用,它专门设计用来利用数千处理器(以附加网络上单个计算机的形式)。对于任何给定的多线程程序,执行有用工作的线程数将

2017-10-18 22:58:18 480

原创 《C++ Concurrency in Action》笔记29 设计并行代码(1)

8 设计并行代码在设计并行代码时要比设计顺序代码时考更过,不仅包括封装、耦合、聚合,而且需要考虑哪些数据需要共享,怎样同步访问数据,哪些线程需要等待其他线程完成工作等等。在这一章,我们将聚焦于这些问题,着眼于高层级(也是基本的)考虑多线程用法,哪些代码执行在哪些线程上,它们对代码清晰度的影响,以及探寻作为共享数据的数据结构的细节以提升性能。首先来看看如何在线程间划分工作。8.1

2017-10-13 12:00:40 612

原创 《C++ Concurrency in Action》笔记28 无锁并行数据结构

7 设计无锁并行数据结构mutex是一种强大的工具,可以保证多个线程安全访问数据结构。使用mutex的目的很直接:访问被保护数据的代码要么锁定了mutex,要么没有。然而,它也有不好的一面,错误的使用它会导致死锁,你也看到了基于锁的队列、查询表例子,所得粒度可以影响并发性能。如果你能写不使用锁的数据结构,那就可以避免这些问题。这样的数据结构叫做无锁数据结构。在这一章,你将看到如何使用第

2017-10-04 23:01:17 869

原创 《C++ Concurrency in Action》笔记27 基于锁的并行数据结构

6 设计基于锁的并行数据结构如果一个数据结构可以被多个线程访问,要么因为他的数据是一直不变的因而不需要做任何同步手段,要么则需要做同步手段以保证不同线程能够正确访问。一种方法就是使用一个独立的mutex然后在外部锁定它,保证数据被保护,就像我们在第3章和第4章中看到的那样;另一种方法是将数据结构本身设计成可并行访问的。当我们设计一个支持并行访问的数据结构时,你可以使用多线程应用的基本构

2017-10-02 11:21:31 558

原创 《C++ Concurrency in Action》笔记26 原子操作和强制排序

5.3 同步操作和强制排序假如你有2个线程,一个填充数据,另一个读取数据。它们通过一个标志位来达到同步的目的:std::vector data;std::atomic data_ready(false);void reader_thread(){ while (!data_ready.load())//(1) { std::this_thread::sleep(std::mi

2017-09-29 15:03:04 940

原创 《C++ Concurrency in Action》笔记25 std::atomic<>类模板、全局函数

现在我们已经了解了所有基本的原子类型,它们都是std::atomic类模板。5.2.6 std::atomicstd::atomic最后,这个类型还需要具有按位可比性(bitwise equality comparable)。这个要求是与赋值操作并驾齐驱的,它不只要求可以使用memcpy() 进行拷贝,还要能够使用memcmp()进行比较。这些要求最终的目的是为了能够正确的执行“比较/

2017-09-28 22:49:10 1152

原创 《C++ Concurrency in Action》笔记24 std::atomic<T*>、std::atomic<整型>

5.2.4 std::atomic相关操作某种类型指针的原子类型就是std::atomic,就像bool类型的原子类型是std::atomic一样。接口从本质上来说是一样的。它不支持拷贝构造和拷贝赋值,尽管他可以从对应的非原子类型的指针构造以及赋值。它也有load(),store() ,exchange(),compare_exchange_weak(),以及compare_exchang

2017-09-28 18:54:04 485

原创 《C++ Concurrency in Action》笔记23 std::atomic<bool>

5.2.3 std::atomic的相关操作最基本的内置类型就是std::atomic,这是个比atomic_flag更为全面的bool量。尽管它仍然不支持拷贝构造和拷贝赋值,但是它可以从一个非原子类型的bool量构造,也可以用一个非原子类型来给std::atomic赋值:std::atomic b(true);b=false;需要注意的是,复制操作并不像我们平时那样返回对象引用,而

2017-09-28 12:14:50 4060

原创 《C++ Concurrency in Action》笔记22 std::atomic_flag

std::atomic_flag是最简单的标准原子类型,它代表一个bool状态。这个状态只有两个值:set和clear。到目前为止,我还没发现在在哪使用它,除非再特殊的场景下。 std::atomic_flag对象必须被ATOMIC_FLAG_INIT初始化,它会将std::atomic_flag初始化为clear状态。这是没有选择余地的,atomic_flag总是以clear状态初始化。

2017-09-27 21:51:48 287

原创 《C++ Concurrency in Action》笔记21 内存模型基础

截止到目前,我们只是讨论了高层级的操作,下面我们将讨论低层级的操作:C++内存模型和原子操作。很多程序员都没有注意到一种非常重要的C++11特性。那不是词法特性,也不是新的库支持,而是新的多线程相关的内存模型。没有内存模型去确切的定义基本结构如何工作,那么之前讨论的所有同步机制就无法实现。大部分人不关心这点的原因是:使用了mutex、condition_variable、future来做同步后

2017-09-26 23:08:07 564

原创 《C++ Concurrency in Action》笔记20 带有消息传递的多线程实现--ATM

一个使用子线程执行任务的简单实现:templatestd::future::type> spawn_task(F&& f, A&& a){ typedef std::result_of::type result_type; std::packaged_task task(std::move(f))); std::future res(task.get_future());

2017-09-26 10:14:39 680

原创 《C++ Concurrency in Action》笔记19 限时等待、FP并行编程

有时,当你阻塞以等待一个事件的发生时,你希望对等待的时间做一些限制。这时,一些具有时间限制的等待函数可以满足你的要求。限时等待限时等待允许你在交互操作中告诉对方,你“仍然活着”;或者如果用户点击了取消按钮,仍然可以结束等待状态。有两种超时方式你可以选择:一种是时间长度,另一种是时间点。大多数的等待函数都同时提供了这两种方式,设置等待时间长度的函数以_for作为后缀,而设置等待的时间点的

2017-09-25 15:55:36 350

原创 《C++ Concurrency in Action》笔记18 std::shared_future

std::future有个限制,那就是只能被一个线程等待。如果你希望从多个线程等待一个相同的事件,那就应该使用std::shared_future。等待多个线程尽管future对数据从一个线程到另一个线程传送作了所有的必要处理,但是调用同一个future实例的成员函数的不同线程却不会彼此同步。如果你访问单一的来自多个线程的fuure实例,没有附加的同步手段,那么你将导致数据竞争。因为,一个

2017-09-25 15:01:50 919

原创 关于std::promise的set_value_at_thread_exit

当std::promise对象执行set_value_at_thread_exit()函数时,先为其关联的future设置值,然后当所在线程A(执行这个函数的线程)的所有本地对象销毁后再将其关联的future的状态设置为ready,而且其他正在等待这个异步状态的线程直到线程A退出后才会结束阻塞状态。对于这种特性,一个重要的应用场景是:当开启一个线程后,对其执行detach()操作后,如果希望再

2017-09-25 10:36:57 1982

原创 《C++ Concurrency in Action》笔记17 promise

当你编写一个需要处理很多网络连接的程序时,你往往倾向于将在每个线程中处理一个连接,这样更容易设计和实现。这比较适合少量连接的情况。随着连接数的增加,这变得越来越不可能,太多的线程消耗过多的系统资源,以及潜在的引发频繁的上下文切换(当线程数操作可硬件能提供的最大并发数时),影响效率。在极端的情况下,可能将操作系统资源耗尽。在这种维护大量网络连接的应用中,通常的做法是使用少量的线程来处理连接,每个

2017-09-24 10:59:31 403

原创 C++11 多线程之传递package_tast讨论

《C++ Concurrency In Action》中有一段这样的示例:许多GUI框架的GUI更新都是通过一个指定的线程来实现的,所以其他线程如果想更新界面必须给指定的线程发送信号。std:packaged_task提供一种方法,可以不用定义自定义消息,如下:std::mutex m; std::deque > tasks; bool gui_shutdown_message_r

2017-09-23 20:44:19 735

原创 《C++ Concurrency in Action》笔记16 future

当线程需要等待一个数据的有效性时,condition_variable就显得不是很适合了,此时应该使用futures。想象你将要坐飞机去休假,办完手续后你需要几个小时去等待飞机起飞。此时你会选择做一些事情来打发时间,比如喝咖啡、看书等等,但根本上讲你只为等一件事:登机。而且,你本次等的航班是唯一的。下次你再旅行就要等待另一趟航班。C++标准库将这种一次性事件称作一个future。如果一个线

2017-09-21 21:03:02 259

原创 《C++ Concurrency in Action》笔记15 a thread-safe queue with condition variable

我们在标准std::queue上做出如下修改:1.将pop()和top()合并为一个函数。2.新增一个 try_pop()函数,不管是否pop成功都立刻返回。2.新增一个wait_and_pop()函数,一直等待,直到有元素可以pop。一个不是很完整的简化示例代码如下:templateclass threadsafe_queue{private:    muta

2017-09-21 19:57:41 355

原创 《C++ Concurrency in Action》笔记14 condition_variable

有时候,你不仅仅需要保护数据,还要在线程之间做同步执行。一个线程可能需要等待一个线程完成一个任务后再继续执行。例如:一个线程等待一个时间发生或者一个条件达成。尽快通过周期判断一个标志或者一些保存在共享数据中的类似的东西可能达到目的,但这并不是理想的做法。在线程间进行同步操作是如此的寻常,C++标准库提供了灵活的手段:condition variables和futures。假如你正坐在旅行的火车

2017-09-21 09:33:33 329

原创 《C++ Concurrency in Action》笔记13 std::recursive_mutex

对于一个std::mutex对象,如果你已经锁定它了,那么在unock()之前你就不可以再次对他执行lock()函数。但在有些情况下,可能希望在解锁前多次锁定一个mutex。对于这种情况,C++标准库提供了std::recursive_mutex。他与std::mutex用法一样,除了可以在一个线程中多次lock一个recursive_lock。但是它要求,在其他线程使用这个lock前,你必须保证

2017-09-20 23:17:16 2281

原创 《C++ Concurrency in Action》笔记12 boost::shared_mutex

如果多线程访问的数据在大部分时刻都是被读,只有极少的几率被写,那么如果使用mutex可能会导致效率低下。但是C++11并没有相应的手段,尽管一种方案被提交给C++委员会,但是没有通过。它就是boost::shared_mutex,它不是灵丹妙药,而且他的效率依赖于计算机的核数以及线程处理的工作量。对于超大规模的系统来说,它是具有实在的益处的。对于需要做数据更新操作的线程,可以使用lock_gu

2017-09-20 22:48:08 547

原创 《C++ Concurrency in Action》笔记11 同步初始化

有时,不太好确定锁定的粒度究竟应该多大,因为并不是所有对共享数据结构的请求都在一个层级上。此时,另一种机制也许可以代替普通的mutex。一种极端的情况是,共享数据仅仅在初始化时需要同步,初始化之后就再也不需要做同步操作了。这也许是因为:要么这是一种只读数据;要么它的所有操作都隐含着相应的保护机制。再者,纯粹为了保护数据初始化而使用mutex是没必要的,也是有损性能的。为此,C++标准提供了一种

2017-09-20 18:06:29 214

原创 《C++ Concurrency in Action》笔记10 选择合适的lock粒度

先看一个简单的示例:class X{public: string some_detail; std::mutex m;public: X(string const& sd) :some_detail(sd) {} friend void swap(X& lhs, X& rhs) { if (&lhs == &rhs) return; std::unique_loc

2017-09-20 12:06:53 295

原创 std::chrono::duration详解

std::chrono::duration(下文简称duration)是标准库中用来代表时间段的一个类模板。QQ:114211200摘抄部分源码:template > class duration;//声明template<class _Rep, class _Period> class duration { // represents a time durationpub

2017-09-19 14:22:10 16379 2

原创 std::ratio 详解

(QQ:114211200)std::ratio代表一个比例,或者说比率。其实就是将给定的两个整数分别除以它们的最大公约数得到一个分数(分子及分母)。其定义为(vs2015):templatestruct ratio{    // holds the ratio of _Nx to _Dx    static_assert(_Dx != 0, "zero denominat

2017-09-18 13:45:03 4074

原创 《C++ Concurrency in Action》笔记9 std::unique_lock源码分析

std::unique_lock提供与std::lock_guard 相同的RAII -style锁管理机制,但是更加灵活。要想理解unique_lock,最好的办法就是看他的源码(vs2013):template class unique_lock { // whizzy class with destructor that unlocks mutexpublic: typede

2017-09-17 13:34:56 456 1

原创 《C++ Concurrency in Action》笔记8 死锁(2)避免死锁

死锁大多由lock引起,但是有时候没有执行lock操作仍然可以引起死锁。例如,两个线程互相jion导致的死锁;或者多个线程形成的一个循环join导致的死锁。避免死锁的方法可以归结为一句话:不要等待另一个线程,如果它此时正在等待你。下面是作者提供的如果识别和消除死锁的几个准则:一、避免嵌套锁首先的建议是,不要重复锁定。如果你已经锁定了就不要再次锁定。如果想同时对多个对象进行锁定操作,那么使用

2017-09-16 23:28:15 295

原创 《C++ Concurrency in Action》笔记8 死锁(1)

就像之前关于top和pop的讨论,他的问题本质上来说是因为lock了太小的单元,保护并不能覆盖几个操作的组合。但是,另一方面,如果lock了太大的范围,同样也能导致问题。极端的情况就是一个全局mutex对象保护了所有的共享数据。在一个存在着大量共享数据的系统中,这将抵消并发带来的任何效益增值,因为它强迫在同一时刻只能运行一个线程,即使这些线程访问的是不同的共享数据。Linux内核的第一个版本就是被

2017-09-16 19:01:32 308

原创 《C++ Concurrency in Action》笔记7 mutex(3)pop和top问题之示例

采用上一篇所说的方案一和方案三定义的一个线程安全的stack,它其实是个stack的包装类,代码如下:struct empty_stack : exception{ const char* what() const throw() { return "the stack is empty"; };};templateclass threadsafe_stack{priva

2017-09-16 18:38:34 227

原创 《C++ Concurrency in Action》笔记7 mutex(3)pop和top问题之方案

接着上一篇笔记,如何解决,top、pop问题。方案一让pop()以参数的形式返回一个引用。std::vector result;some_stack.pop(result);这种方案在大多数情况下都能正常工作。但是它有个严重的缺点,就是需要再调用pop前先构造一个值的实例。有时,这是不切实际的,因为这需要花费时间或资源。另一方面,这也不总是可行的,因为构造一个示例所需的参数在某个

2017-09-16 17:50:29 275

原创 《C++ Concurrency in Action》笔记7 mutex(2)pop和top问题

虽然在类中封装mutex可以对数据进行并发保护,但是有些时候光对每个操作进行保护是不够的。看下面的代码:template >class stack{public:explicit stack(const Container&);explicit stack(Container&& = Container());template explicit stack(const Alloc

2017-09-16 16:18:21 326

原创 《C++ Concurrency in Action》笔记7 mutex(1)

C++标准库提供了std::mutex类作为互斥量,提供了lock()和unlock()成员函数,但是不建议直接使用这两个成员函数。如果漏写其中之一将导致错误,包括产生异常时的处理,都很容易出错。C++提供了一个类模板std::lock_guard,它对一个mutex实现了RAII机制,在构造时锁定mutex,析构时解锁mutex。保证在绝大多数情况下每一次lock都对应一个unlock。

2017-09-16 14:39:48 199

原创 《C++ Concurrency in Action》笔记6 Avoiding problematic race conditions

阻止竞争问题的几种办法:1.保证每一个时刻只有一个线程在修改数据。C++标准提供了若干机制。2.无锁编程(lock-free programming),本书第七章介绍。3.software transactional memory ( STM ),本书未做讲解。

2017-09-16 14:21:47 259

自编MStirng(类似std::string)以及配套的4种iterators

自己编写的string类,名字叫做MString。并且编写了配套的iterator、const_iterator、reverse_iterator、const_reverse_iterator。完全支持stl的各种算法,包括支持insert_iterator()转换。编写它的目的不是为了使用,而是为了熟悉stl算法及迭代器的原理。其中MString仅支持简单的基本操作,但在此基础上扩展其他功能已经很容易。主要精力放在了iterator的编写上,iterator开发了全部功能,使用了模板,使得代码非常简短。

2017-09-10

文件夹内文件对比2.0

选择两个路径:A、B,点击对比,会将两个路径下的相同的文件名(A=B)以及不同的文件名(A-B、B-A)等详细信息列出。延续上一版功能,对代码作进一步优化,修改一处bug。同时新增功能:是否对比文件修改时间、是否对比文件夹、在资源管理器中显示对比结果(打开资源管理器并选中多个项目(文件、文件夹))

2015-05-30

打开文件夹(资源管理器),选中多个文件(文件夹)

打开一个资源管理器并选中多个目标(文件、文件夹)。在国内网站搜索很久没有找到相关代码,后来在一个网站上找到了使用SHOpenFolderAndSelectitems函数来打开资源管理器,但是只能选中一个目标,因此在他的基础上测试并修改实现了所需功能。

2015-05-30

文件夹内文件名对比

选择两个路径:A、B,点击对比,会将两个路径下的相同的文件名(A=B)以及不同的文件名(A-B、B-A)等详细信息列出

2012-09-07

文件内容替换(遍历所有文件)

指定一个文件夹路径,设置替换信息,点击“替换”按钮则开始替换,还有导入导出替换信息。

2012-01-09

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除