
C++并发实战
文章平均质量分 71
liuxuejiang158
做点笔记,省的百度不到。。。
展开
-
C++并发实战2:thread::join和thread::detach
thread::join()是个简单暴力的方法,主线程等待子进程期间什么都不能做,一般情形是主线程创建thread object后做自己的工作而不是简单停留在join上。thread::join()还会清理子线程相关的内存空间,此后thread object将不再和这个子线程相关了,即thread object不再joinable了,所以join对于一个子线程来说只可以被调用一次,为了实现更精细的原创 2013-12-02 14:11:29 · 36764 阅读 · 2 评论 -
C++并发实战11:条件变量
1 线程睡眠函数std::this_thread::sleep_for(std::chrono::milliseconds(100));//头文件#include,供选择的如seconds()等 不要使用睡眠函数同步线程,睡眠函数可以用于复现线程的一些行为。2 条件变量std::condition_variable不允许拷贝和移动的。其基本语义和Linux的pthr原创 2013-12-13 12:45:59 · 5758 阅读 · 0 评论 -
C++并发实战18: 线程安全的查找表和链表
经常遇见根据关键字查找内容的应用如DNS查询,标准库的std::map系列可供选择,但是它们是非线程安全的,一个线程安全的查找表实现如下,其主要是通过hash函数将各个key分散到具体的bucket中去,每个bucket带有一个共享锁boost::shared_mutex,从而实现线程安全的高并发数据结构:#include #include #include #include #inc原创 2013-12-25 14:22:16 · 7539 阅读 · 0 评论 -
C++并发实战19:lock free编程
涉及到并行/并发计算时,通常都会想到加锁,加锁可以保护共享的数据,不过也会存在一些问题:1. 由于临界区无法并发运行,进入临界区就需要等待,加锁使得效率的降低。多核CPU也不能发挥全部马力2. 在复杂的情况下,很容易造成死锁,并发进程、线程之间无止境的互相等待。3. 在中断/信号处理函数中不能加锁,给并发处理带来困难。4. 加锁影响实时性,等待时间不确定5. 优先级反转,优先级原创 2013-12-26 12:50:44 · 5701 阅读 · 0 评论 -
C++并发实战16: std::atomic原子操作
针对原子类型操作要不一步完成,要么不做,防止由于多线程串行化带来的错误。1 std::atomic_flag是一个bool原子类型,其支持test_and_set和clear两个操作,atomic_flag内部维护一个状态flag。atomic_flag::test_and_set检查flag是否被设置,若被设置直接返回true,若没有设置则设置flag为true后再返回false。atom原创 2013-12-19 15:50:03 · 95352 阅读 · 7 评论 -
C++并发实战:面试题1:一道多线程笔试题
题目:子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次,试写出代码。#include#include#include#includeusing namespace std;mutex m;condition_variable cond;int flag=10;void fun(int num原创 2014-03-24 18:17:27 · 8856 阅读 · 4 评论 -
C++并发实战:面试题3:一道google笔试题
题目:有四个线程1、2、3、4。线程1的功能就是输出1,线程2的功能就是输出2,以此类推.........现在有四个文件ABCD。初始都为空。现要让四个文件呈如下格式:A:1 2 3 4 1 2....B:2 3 4 1 2 3....C:3 4 1 2 3 4....D:4 1 2 3 4 1....c++11代码:#include#include#include原创 2014-03-25 22:27:12 · 5100 阅读 · 1 评论 -
C++并发实战:面试题4:生产者消费者试题blocking queue
生产者消费者问题这是一个非常经典的多线程题目,题目大意如下:有一个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个有多个缓冲区的缓冲池,生产者将它生产的产品放入一个缓冲区中,消费者可以从缓冲区中取走产品进行消费,所有生产者和消费者都是异步方式运行的,但它们必须保持同步,即不允许消费者到一个空的缓冲区中取产品,也不允许生产者向一个已经装原创 2014-03-27 13:19:15 · 6021 阅读 · 0 评论 -
C++并发实战13:std::future、std::async、std::promise、std::packaged_task
std::condition_variable可以用于异步事件的重复通知,但是有些时候可能只等待事件发生一次,比如:等待特定的航班,用条件变量大杀器有点浪费了。C++11标准库提供了几种异步任务机制。通常thread不能返回线程执行的结果(可以通过引用参数返回),而在异步处理当中很多时候都需要获得计算的结果。如果只获取结果一次那么选用future,即通过future获取了结果后,后续再通过此fut原创 2013-12-16 20:05:26 · 18772 阅读 · 2 评论 -
C++并发实战:面试题5:读者写者问题copy on write
读者写者问题这也是一个非常经典的多线程题目,题目大意如下:有一个写者很多读者,多个读者可以同时读文件,但写者在写文件时不允许有读者在读文件,同样有读者读时写者也不能写。这里采用copy on write(写时拷贝)实现,主要要理解智能指针std::shared_ptr的用法,用访问vector替代题目中的文件,代码如下:#include#include#原创 2014-03-27 14:51:59 · 6132 阅读 · 2 评论 -
C++并发实战:面试题2:一道迅雷笔试题
题目:编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。采用C++11实现:#include#include#include#includeusing namespace std;mutex m;condition_variable cond;int LO原创 2014-03-25 14:35:01 · 4939 阅读 · 0 评论 -
C++并发实战15:函数式编程
函数y=f(x)就是个x->y的映射,其仅仅是x和y的关系,其运算关系仅仅是依赖参数x并不涉及其它外部状态。在函数式编程中,每个语句是一个表达式都是执行单纯的计算并有返回值,而C中的语句是执行某种操作如赋值,且计算是由函数完成的,仅仅依赖于输入参数。如一条简单的函数语句,功能是(1+2)*3-4:var result = subtract (multiply (add (1,2), 3), 4原创 2013-12-18 15:33:07 · 4553 阅读 · 0 评论 -
C++并发实战14:时间
std::chrono::system_clock::now()//返回系统当前时间 时钟周期:std::ratio //表示1s内25个周期 std::chrono::system_clock::is_steady() //测试系统时钟周期是否可调 std::chrono::duration > //时间间隔,第一个参数short(或long,doubl原创 2013-12-17 14:42:30 · 3935 阅读 · 0 评论 -
C++并发实战12:线程安全的queue
1 首先看下STL中的queue的接口:template >class queue { public: explicit queue(const Container&); explicit queue(Container&& = Container()); template explicit queue(const Alloc&); template原创 2013-12-13 15:16:30 · 22160 阅读 · 11 评论 -
C++并发实战7:thread::mutex
创建一个互斥量std::mutex; mutex::lock(),mutex::unlock()互斥量的加锁解锁,try_lock未加锁时加锁否则不加锁返回false。但是不建议直接使用lock和unlock,因为这样需要在各种情形下保证lock和unlock的匹配,即使是抛出异常。标准库中采用RAII手法封装了mutex的类std::lock_guard在构造时lock,析构时unlock。lo原创 2013-12-10 10:51:32 · 4308 阅读 · 1 评论 -
C++并发实战3:向thread传递参数
在创建thread object时可以向线程传递参数,默认情况下,参数会被拷贝到线程空间以供线程执行时存取,即使参数是引用也是这样。情形1:void f(int i,std::string const& s); boost::thread t(f,3,”hello”); //字符串常量“hello”会被转换为string,该string在线程中存在。原创 2013-12-03 15:01:49 · 19276 阅读 · 5 评论 -
C++并发实战1:thread object
boost::thread的使用首先确定安装了boost,ubuntu采用:sudo apt-get install libboost-dev再安装:sudo apt-get install libboost-thread编写如下文件:#include#include#include#includeusing namespace std;void show(){原创 2013-11-29 18:15:15 · 10630 阅读 · 9 评论 -
C++并发实战8:deadlock
1 死锁:每个线程都希望锁住一些列锁以执行某个操作,且每个线程持有一个不同的锁,最终每个线程都需要其它线程的锁,导致所有线程都不能向前执行。 1.1 顺序加锁lock 1.1 死锁的一个解决方式:每个线程对锁的请求顺序一致。C++库提供了顺序加锁机制,可以一次性锁住多个mutex而不会出现死锁:void lock (Mutex1原创 2013-12-11 14:15:23 · 3688 阅读 · 2 评论 -
C++并发实战4:thread object is movable,not copyable
假设这样一个情形:假设函数A创建一个thread object返回给A的调用者,或者A将thread obejct转移给其它函数。thread object is movable but no copyable like std::unique_ptr or std::ifstream可以看出thread object是可以转移其所有权的。void some_function();void原创 2013-12-03 17:56:57 · 3069 阅读 · 1 评论 -
C++并发实战5:并行化的std::accumulate
std::thread::hardware_concurrency()可以返回CPU个数,在C++库不能获取CPU信息下可能返回0。该信息是非常有用的,当线程数超过CPU cores会频繁的引起上下文切换,返回会降低性能,当hardware_concurrency()返回0时可以指定一个数目比如2。 下面给出一个并行化的std::accumulate()的例子:std::ac原创 2013-12-04 16:46:21 · 4644 阅读 · 3 评论 -
C++并发实战6:thread::id
线程标识符id可以通过thread::get_id()获得,若thread obejct没有和任何线程关联则返回一个NULL的std::thread::id表示没有任何线程。当前线程若想获得自己的id可以调用std::this_thread::get_id()。 thread::id对象可以被任意复制和比较。这里的比较语义是:若相等表示是同一个线程或者都没有线程,不等表示不同的原创 2013-12-04 17:37:07 · 4576 阅读 · 0 评论 -
C++并发实战9:unique_lock
1 回顾采用RAII手法管理mutex的std::lock_guard其功能是在对象构造时将mutex加锁,析构时对mutex解锁,这样一个栈对象保证了在异常情形下mutex可以在lock_guard对象析构被解锁。explicit lock_guard (mutex_type& m);//必须要传递一个mutex作为构造参数lock_guard (mutex_type& m, adopt_原创 2013-12-11 16:36:31 · 18608 阅读 · 3 评论 -
C++并发实战10:保护共享数据的可选机制
使用mutex的时候要尽量缩小临界区,若可能的话,对mutex加锁仅仅是为了获取共享数据,而对数据的计算放在临界区之外。a lock should be held for only the minimum possible time needed to perform the required operations。一个非常好的实例就是copy on write。不要在临界区内进行IO,IO比内存原创 2013-12-12 11:39:36 · 3430 阅读 · 0 评论 -
C++并发实战17:线程安全的stack和queue
1 线程安全的数据结构有几个可以注意的地方:当一个线程看见invariants时其他线程不会破坏该invariants,比如一个线程在遍历访问vector另一个线程却在修改vector这就破坏了variants;注意数据结构接口引起的竞态,必要的时候将多个操作合并;注意异常的处理;避免局部操作的锁超出其作用范围,否则可能引起死锁;尽可能的缩小临界区。 线程安全的栈关键代码:#in原创 2013-12-24 16:59:31 · 7333 阅读 · 1 评论 -
C++并发实战:面试题6:线程一次性同步
是否熟悉POSIX多线程编程技术?如熟悉,编写程序完成如下功能:1)有一int型全局变量g_Flag初始值为0;2) 在主线称中起动线程1,打印“this is thread1”,并将g_Flag设置为13) 在主线称中启动线程2,打印“this is thread2”,并将g_Flag设置为24) 线程序1需要在线程2退出后才能退出5) 主线程在检测到g_原创 2014-03-27 16:44:58 · 6797 阅读 · 0 评论