多线程
c++多线程
低头看天,抬头走路
句句都是正确的废话,招招都是致命的空招。
展开
-
常用lock-free编程
RCURCU 的关键思想有两个:1)COW,复制后更新;2)延迟回收内存。典型的RCU更新时序如下:复制:将需要更新的数据复制到新内存地址;更新:更新复制数据,这时候操作的新的内存地址;替换:使用新内存地址指针替换旧数据内存地址指针(内存地址替换操作是原子的),此后原有读者访问旧数据,新的读者将访问新数据;等待: 所有访问旧数据的读者进入静默期(QS),说明之前的reader都离开了临界区, 这个时候访问旧数据完成;回收:当所有的CPU都至少经历过一次QS后, 意味着宽限期的结束,因此就进行回原创 2020-12-21 23:27:05 · 747 阅读 · 0 评论 -
C++并行编程
相关概念并发:宏观上是同时,微观上仍是顺序执行并行:同时间执行数据安全访问方式样例备注lock互斥锁,读写锁,自旋锁锁的切换有开销memory barrier内存屏障编译器与cpu无法乱序执行,无法得到相应加速效果atomicatomic适用于基本类型CAScpu层面原子指令修改内存,内存栅栏保障修改可见,必要时锁总线1.适合冲突较少的简单对象的操作,如果太多线程同时自旋,那么长时间循环会导致 CPU 开销大; 2.ABA问题(引入变量版本号解原创 2020-12-09 00:17:37 · 565 阅读 · 0 评论 -
c++ 线程间通信方式
线程同步和线程互斥互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的,线程间不需要知道彼此的存在。同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问,线程间知道彼此的存在。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源线程...原创 2019-07-28 23:07:51 · 39810 阅读 · 4 评论 -
std::unique_lock与std::lock_guard区别
使用方式lock_guard:通过构造函数和析构函数控制锁的作用范围,创造对象的时候加锁,离开作用域的时候解锁;std::mutex m_mutex;void print(int cnt){ std::lock_guard<mutex> lock(m_mutex); cout << std::this_thread::get_id() <<...原创 2020-03-04 12:07:14 · 4880 阅读 · 0 评论 -
notify和unlock的顺序
虚假唤醒即使没有线程向条件变量发出信号,线程也可能从等待状态中唤醒。注:虚假唤醒很容易被人误解为:如果有多个消费者,这些消费者可能阻塞在同一位置。当生产者通知not empty时,duque立即被第一个被唤醒的消费者清空,则后面的消费者相当于时被虚假唤醒了。这种情况完全可以通过使用signal而非broadcast解决。signal只会唤醒某个线程,唤醒的依据为等待线程的优先级,若优先级相同...原创 2020-01-15 00:43:26 · 1632 阅读 · 0 评论 -
C++死锁
现象:程序夯住考虑方向:死循环:CPU100%死递归: 栈溢出死锁: CPU 0产生死锁的条件有四个:1.互斥条件:所谓互斥就是进程在某一时间内独占资源。2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。3.不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺。4.循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。只要打破四个必要条件之一就...原创 2019-08-23 14:29:55 · 161 阅读 · 0 评论