atomic

Atomic exchange of two std::atomic<T*> objects in a lock-free manner in C++11?

帅比萌擦擦* 提交于 2020-08-24 06:09:30
问题 The following code is a skeleton of an atomic pointer class taken from a simulated annealing application in the PARSEC benchmark suite for shared-memory multiprocessors. In that application, the central data structure is a graph (more specifically, a netlist of an integrated circuit). Each node in the graph has an attribute indicating its physical location. The algorithm spawns many threads and each thread repeatedly and randomly selects two nodes and exchanges their physical locations if

atomic<bool> vs bool protected by mutex

本秂侑毒 提交于 2020-08-23 04:55:28
问题 Let's assume we have a memory area where some thread is writing data to. It then turns its attention elsewhere and allows arbitrary other threads to read the data. However, at some point in time, it wants to reuse that memory area and will write to it again. The writer thread supplies a boolean flag ( valid ), which indicates that the memory is still valid to read from (i.e. he is not reusing it yet). At some point he will set this flag to false and never set it to true again (it just flips

Java并发问题--乐观锁与悲观锁以及乐观锁的一种实现方式-CAS

China☆狼群 提交于 2020-08-20 09:19:40
首先介绍一些乐观锁与悲观锁:   悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。再比如 Java里面的同步原语 synchronized关键字的实现也是悲观锁 。   乐观锁:顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁, 但是在更新的时候会判断一下在此期间别人有没有去更新这个数据 ,可以使用版本号等机制。 乐观锁适用于多读的应用类型 ,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在 Java中java.util.concurrent.atomic包下面的 原子变量类就是使用了乐观锁的一种实现方式CAS实现的 。 乐观锁的一种实现方式-CAS(Compare and Swap 比较并交换):   锁存在的问题:      Java在JDK1.5之前都是靠 synchronized关键字保证同步的 ,这种通过使用一致的锁定协议来协调对共享状态的访问,可以确保无论哪个线程持有共享变量的锁,都采用独占的方式来访问这些变量。这就是一种独占锁,独占锁其实就是一种悲观锁,所以可以说 synchronized 是悲观锁。  

input输入子系统

时光怂恿深爱的人放手 提交于 2020-08-20 09:16:36
一、什么是input输入子系统? 1、Linux系统支持的输入设备繁多,例如键盘、鼠标、触摸屏、手柄或者是一些输入设备像体感输入等等,Linux系统是如何管理如此之多的不同类型、不同原理、不同的输入信息的 输入设备的呢?其实就是通过input输入子系统这套软件体系来完成的。从整体上来说,input输入子系统分为3层:上层(输入事件驱动层)、中层(输入核心层)、 下层(输入设备驱动层),如下图所示: 联系之前学过的驱动框架做对比,input输入子系统其实就是input输入设备的驱动框架,与之前的学过的驱动框架不同的是,input输入子系统分为3层:上、中、下,所以他的复杂度 要高于之前讲的lcd、misc、fb等的驱动框架。 2、图中Drivers对应的就是下层设备驱动层,对应各种各样不同的输入设备,Input Core对应的就是中层核心层,Handlers对应的就是上层输入事件驱动层,最右边的代表的是用户空间。 (1)从图中可以看出,系统中可以注册多个输入设备,每个输入设备的可以是不同的,例如一台电脑上可以带有鼠标,键盘....。 (2)上层中的各个handler(Keyboard/Mouse/Joystick/Event)是属于平行关系,他们都是属于上层。不同的handler下对应的输入设备在应用层中的接口命名方式不一样,例如 Mouse下的输入设备在应用层的接口是 /dev

99 道 Java 多线程面试题,看完我跪了!

老子叫甜甜 提交于 2020-08-19 23:56:45
今天给大家更新的是一篇关于多线程面试的文章,是根据时下热门的面试内容给大家进行总结的,如有雷同,请多见谅。 本篇文章属于干货内容!请各位读者朋友一定要坚持读到最后,完整阅读本文后相信你对多线程会有不一样感悟,下次面试和面试官也能杠一杠相关内容了。 1.什么是进程? 进程是系统中正在运行的一个程序,程序一旦运行就是进程。 进程可以看成程序执行的一个实例。进程是系统资源分配的独立实体,每个进程都拥有独立的地址空间。一个进程无法访问另一个进程的变量和数据结构,如果想让一个进程访问另一个进程的资源,需要使用进程间通信,比如管道,文件,套接字等。 2.什么是线程? 是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。 3.线程的实现方式? 1.继承Thread类 2.实现Runnable接口 3.使用Callable和Future 4.Thread 类中的start() 和 run() 方法有什么区别? 1.start()方法来启动线程,真正实现了多线程运行。这时无需等待run方法体代码执行完毕,可以直接继续执行下面的代码;通过调用Thread类的start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。然后通过此Thread类调用方法run(

Atomic struct containing pointer

隐身守侯 提交于 2020-08-19 12:20:52
问题 #include <atomic> #include <iostream> using namespace std; struct Simple{ int a = 0; int b = 0; }; struct WithPointer{ int *a = nullptr; int b = 0; }; int main(int argc, char const *argv[]) { atomic<Simple> simple; cout<<simple.is_lock_free()<<"\n"; atomic<Simple*> simple_p; cout<<simple_p.is_lock_free()<<"\n"; atomic<WithPointer> with_pointer; cout<<with_pointer.is_lock_free()<<"\n"; return 0; } This example works fine for the Simple struct but not for the WithPointer struct. I get the

Atomic struct containing pointer

拟墨画扇 提交于 2020-08-19 12:12:09
问题 #include <atomic> #include <iostream> using namespace std; struct Simple{ int a = 0; int b = 0; }; struct WithPointer{ int *a = nullptr; int b = 0; }; int main(int argc, char const *argv[]) { atomic<Simple> simple; cout<<simple.is_lock_free()<<"\n"; atomic<Simple*> simple_p; cout<<simple_p.is_lock_free()<<"\n"; atomic<WithPointer> with_pointer; cout<<with_pointer.is_lock_free()<<"\n"; return 0; } This example works fine for the Simple struct but not for the WithPointer struct. I get the

【JavaSE 并发CAS】原理层面:CAS(AtomicInteger类compareAndSet()方法到底干了什么?)

社会主义新天地 提交于 2020-08-18 14:33:00
文章目录 一、前言 二、CAS操作 2.1 CAS三步操作+CAS与阻塞同步的对比+三种锁 2.1.1 CAS三步操作 2.1.2 CAS与内建锁比较 2.1.3 三种锁 2.2 CAS的应用:AtomicInteger类中的compareAndSet()方法使用for+if(cas)保证线程安全 2.2.1 从AtomicInteger类incrementAndGet()方法的源码出发,开启底层探索 2.2.2 继续深入AtomicInteger类的compareAndSet方法 2.2.3 继续深入native compareAndSwapInt()方法 2.2.4 继续深入UNSAFE_ENTRY()方法 2.2.5 继续深入的Atomic::cmpxchg() 三、CAS的ABA问题 3.1 什么是ABA问题(理论解释,一图就好了) 3.2 代码重现ABA问题(代码,面试没用) 3.3 ABA问题:原因、突破口、解决方式、源码支持 3.3.1 ABA问题的产生原因(背诵) 3.3.2 ABA问题:从原因到突破口再到解决方式(背诵) 3.3.3 ABA问题两个类的源码:不仅比较数值,还有比较当前的数值是否被修改过 1、AtomicStampedReference类 2、AtomicMarkableReference类 3.4 代码解释ABA问题两个类处理 3.4.1

snowflake时间回退问题思考

我是研究僧i 提交于 2020-08-17 18:04:49
算法比较简单,每个id-generator负责生成的ID由3部分组成,41位时间戳可以表示到毫秒,10bit worker-id内部可自行划分,比如3位表示IDC,7位表示机器。最后12位是在一毫秒的递增id,也就是每毫秒算法可以产生2^12 = 4096个id,QPS 400多万; snowflake保证1)产生的id分布式系统内全局唯一,2)id趋势递增;不是严格递增,因为集群的机器时间不同步问题 该算法存在一个最严重的问题,是时间回退。比如一台机器A,在t产生一个id,但时钟被调回了t-15,则再次生成的id存在重复的可能。 思考了一个解决这个问题的方法, 在单一id-generator服务上,每ms生成id时,检测current_ms,或<= last_ms则等待last_ms-current_ms后,再开始正常服务。这样若id-generator重启后依然有问题,因为没有地方记录last_ms。并且因为400w的高qps,也无法将其持久化。 我们引入一个第3方,如zookeeper或redis,id-generator服务启动时atomic increase一个key,并将结果用作worker-id。。。 oops!貌似不行,只支持重启1024次 来源: oschina 链接: https://my.oschina.net/u/4367530/blog/4280303

操作系统中锁的原理(转)

我的梦境 提交于 2020-08-17 16:35:16
1. 概述 为了保证数据的一致性,在多线程编程中我们会用到锁,使得在某一时间点,只有一个线程进入临界区代码。虽然不同的语言可能会提供不同的锁接口,但是底层调用的都是操作系统的提供的锁,不同的高级语言只是在操作系统的锁机制基础上进行了些封装而已,要真正理解锁,还是得看操作系统是怎么实现锁的。 2. 锁的本质 所谓的锁,本质上只是内存中的一个整形数,不同的数值表示不同的状态,比如1表示空闲状态和加锁状态。加锁时,判断锁是否空闲,如果空闲,修改为加锁状态,返回成功,如果已经上锁,返回失败,解锁时,就把锁状态修改为空闲状态。 加锁和解锁看起来都很简单,但是os是怎么保证锁操作本身的原子性呢? 在多核环境中,两个核上的代码同时申请一个锁,两个核同时读取锁变量,同时判断锁是空闲的,再各自修改锁变量为上锁状态,都返回成功,这样两个核同时获取到了锁, 这种情况可能吗? 当然是不可能的,那么os是通过什么手段来保证锁操作本身的原子性的呢?我们可以把上锁的过程具体表示为: 读内存表示锁的变量 判断锁的状态 如果已经加锁,返回失败 把锁设置为上锁状态, 返回成功 上面的每一个步骤都对应一条汇编语句,可以认为这每一步操作都是原子的,什么情况会导致两个线程同时获取到锁? 中断: 当线程A执行完第一步后,发生了中断,os调度线程B,线程B也来加锁并且加锁成功,此时又发生中断,OS调度线程A执行,从第二步开始