C++并发编程实战(读书笔记)——C++内存模型不好理解;无锁数据结构?但是等待不就是被锁住了吗??

C++并发编程实战

基本线程管理[编辑]

  1. p18 RAII:~thread_guard:if(t.joinable())t.join();
  2. p29 std::this_thread::get_id()

在线程间共享数据[编辑]

  1. mutex
    1. p36 std::lock_guard<std::mutex> l(m); //RAII风格
    2. p45 std::lock可以用时锁住2个或更多的mutex?
    3. p46 让每个线程仅持有一个锁,--> 但是仍然有可能相互等待...
    4. p50 层次锁?
    5. p52 std::unique_lock??
  2. p57 臭名昭著的2次检查锁定模式:data race(~ C++内存模型)
    1. std::call_once(std::once_flag f, std::shared_ptr<T> res);
  3. p60 读写mutex:boost::shared_mutex
  4. p61 递归锁(略)

同步[编辑]

  1. std::condition_variable data_cond;
    1. data_cond.wait( lk, []{return !queue.empty()} );
    2. data_cond.notify_one(); //唤醒一个,注意,上面2句都需要在std::unique_lock的保护范围内(queue是共享变量)
  2. p68 threadsafe_queue?
  3. 使用future等待一次性事件
    1. std::future<T> result = std::async(doWork); //将在result.get()时阻塞
  4. std::packaged_task<T=Callable> -> get_future() //高层抽象
  5. std::promise*
    1. set_value / get_future
  6. std::shared_future*
  7. std::chrono::
    1. system_clock, steady_clock, high_resolution_clock
    2. duration
    3. time_point
  8. std::timed_mutex:try_lock_for / try_lock_until
  9. p91 基于future的parallel_quick_sort
  10. p92 spawn_task
    1. typedef std::result_of<F(A&&)>::type result_type; //?

C++内存模型和原子操作[编辑]

  1. std::atomic_flag f = ATOMIC_FLAG_INIT;
    1. lock: while(f.test_and_set(std::memory_order_acquire)); //可以运行时切换std::memory_order_*参数到底是个什么鬼??
    2. unlock: fl.clear(std::memory_order_release);
  2. 更通用的std::atomic<bool>
    1. b.compare_exchange_weak(expected_value, memory_order_acq_rel, memory_order_acquire); //?
  3. std::atomic<T*>上的操作
    1. p108 p.fetch_add(3, std::memory_order_release);
  4. std::atomic<UDT>
    1. UDT必须有平凡的拷贝赋值(且必须是编译器默认生成的,POD?)、必须是按位相等可比较的
  5. 原子操作函数*
  6. p114 happens-before和synchronizes_with
  7. p116 6种内存顺序:
    1. 代表了3种模型:
      1. 顺序一致(最容易理解的,但在多处理器但弱顺序机器上有性能问题)
      2. 非顺序一致:*
        1. ?唯一的要求是所有的线程对每个独立变量的修改顺序达成一致(“达成一致”指的是什么意思???)
      3. 松弛:原子类型上但操作不参与synchronizes_with关系,单线程中的同一个变量的操作仍然服从happens-before关系
      4. p124 获得-释放:靠,仍然有点费解
      5. 获取-释放顺序传递性同步*
      6. p130 memory_order_consume:数据依赖(?)
  8. p133 释放序列和synchronizes_with **
  9. 内存屏障
    1. p137 用原子操作排序非原子操作*

基于锁的并发数据结构[编辑]

  1. p162 设计一个细粒度的map数据结构
    1. RB-tree(std::map)从访问根节点开始,... 尽管线程沿着树往下移动的时候会释放这个锁 ...
    2. 已排序数组
    3. hashmap:可以在每个桶上有一个独立的锁
  2. p165 编写一个使用锁的线程安全链表
    1. 基本思想是每个节点使用一个mutex(细粒度锁)... ?如果要修改相邻的2个节点,需要同时上锁吧?
    2. 可以参考Linux Kernel里的list实现...

设计无锁并发数据结构[编辑]

  1. p174 无锁的线程安全栈*
    1. 不是无等待的!(线程死循环忙等不就相当于被“锁住”了吗?)
    2. p178 管理内存(防止泄露):你想释放一个节点,但必须确保没有别的线程引用时才能这么做,... 这从根本上意味着需要为节点写一个专用GC
    3. p182 用风险指针(hazard pointers)检测不能回收的节点 *
    4. p189 使用引用计数检测节点 *
    5. p194 将内存模型应用至无锁栈 *
  2. p198 无锁队列
  3. 编写无锁数据结构的准则
    1. p210 使用std::memory_order_seq_cst
    2. 使用无锁内存回收模式
    3. 当心ABA问题
    4. 识别忙于等待的循环及辅助其他线程

设计并发代码[编辑]

  1. p219 以任务类型划分工作
  2. p221 划分线程间的任务队列(管道)
  3. 影响性能的因素
    1. p223 数据竞争和缓存乒乓
    2. 假共享(CPU的片内cache line)
  4. 额外考虑
    1. p230 并行算法中的异常安全 *
  5. 在实践中设计并发代码:STL算法的并行实现 **
    1. std::for_each
    2. std::find
    3. std::partial_sum

高级线程管理[编辑]

  1. 线程池
  2. 中断线程(这里的思想似乎来自于Java interrupt()?)

多线程应用的测试与调试[编辑]

  1. 不必要的阻塞:死锁、活锁、IO阻塞
  2. 竞争条件
  3. 多线程测试
    1. ps:Google Android上的Address Sanitizer (ASAN)工具?

附录A C++部分语言特性简明参考[编辑]

附录B 并发类库对比[编辑]

附录C 消息传递框架与完整的ATM示例[编辑]

附录D C++线程类库参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值