volatile

嵌入式学习-MMU

。_饼干妹妹 提交于 2020-04-03 12:04:12
原文: https://blog.csdn.net/u011003120/article/details/51812188 参考: https://blog.csdn.net/groundhappy/article/details/54889677 MMU 存储器管理单元,在之前因为是操作物理地址,不需要MMU,因此是处于关闭状态的,而这次则是打开MMU并且使用MMU. 一、MMU的作用 1.将虚拟地址转化为物理地址 2.进行访问权限的管理 看上图可以得知,有三个运行的程序,他们的虚拟地址都为0x400000,但是若要使用物理地址,他们的物理地址不能够相同,因此就需要一个机制,使他们的相同的虚拟地址对应不同的物理地址,这个机制就是上图中的Page tables(即页表),虚拟地址通过查表的方式对应到不同的物理地址上。 二、地址转化 首先需要知道的是,以段(Section,1M)的方式进行转换时只用到一级页表,而页(Page)的方式进行转换时用到两级页表,有粗也转换和细页转换两种,页的大小有3种:大页(64KB)、小页(4KB)和极小页(1KB)。 1.地址转化总体分析 整个地址转换的过程分为了两步,为一级转换和二级转换。 虚拟地址的[31:20]位作为一个表的索引,表的名字为translation table,即TTB,如果表的后两位为00,则为无效的转换,如上图,如果后两位为01

Happen-before

▼魔方 西西 提交于 2020-03-31 15:12:44
1、程序顺序原则:一个线程内保证语义的串行性 2、volatile规则:volatile变量的写,先发现于读,这保证了volatile变量的可见性 3、锁规则:解锁(unlock)必然发生在随后的加锁(lock)前 4、传递性:A先于B,B先于C,那么A必然先于C 5、线程的start()方法先于它的每一个动作 6、线程的所有操作优先于线程的终结(Thread.join()) 7、线程的终端(interrupt())先于被终端线程的代码 8、对象的构造函数执行结束先于finalize()方法 来源: https://www.cnblogs.com/XuZhiDian/p/7361083.html

java中volatile关键字的含义

人盡茶涼 提交于 2020-03-31 08:05:46
在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉。 Java语言是支持多线程的,为了解决线程并发的问题,在语言内部引入了 同步块 和 volatile 关键字机制。 synchronized 同步块大家都比较熟悉,通过 synchronized 关键字来实现,所有加上synchronized 和 块语句,在多线程访问的时候,同一时刻只能有一个线程能够用 synchronized 修饰的方法 或者 代码块。 volatile 用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值。volatile很容易被误用,用来进行原子性操作。 下面看一个例子,我们实现一个计数器,每次线程启动的时候,会调用计数器inc方法,对计数器进行加一 执行环境——jdk版本:jdk1.6.0_31 ,内存 :3G cpu:x86 2.4G public class Counter { public static int count = 0; public static void inc() { //这里延迟1毫秒,使得结果明显 try { Thread.sleep(1); } catch (InterruptedException e) { } count++; } public

java中volatile,synchronized关键字

人盡茶涼 提交于 2020-03-30 12:59:54
volatile是变量修饰符,而synchronized则是作用于一段代码或方法;如下三句get代码: 1 int i1; 2 int geti1() {return i1;} 3 4 volatile int i2; 5 int geti2() {return i2;} 6 7 int i3; 8 synchronized int geti3() {return i3;} geti1() 得到存储在当前线程中i1的数值。多个线程有多个i1变量拷贝,而且这些i1之间可以相互不同。换句话说,另一个线程可能已经改变了它线程内的i1值,而这个值可以和当前线程中的i1值不相同。 在Java内存模型中,有main memory(主内存区域),这里存放了变量目前的“准确值”,每个线程也有自己的memory(例如寄存器)。为了性能,一个线程会在自己的memory中保存要访问的变量的副本。这样就会出现同一个变量在某个瞬间,在一个线程的memory中的值可能与另外一个线程memory的值,或者main memory的值不一致的情况。因此实际上存在一种可能:main memory的值i1值是1,线程1里的i1是2,线程2里的i1值是3,这在线程1和线程2都改变了他们各自的i1值,而且这个改变还没来得及传给main memory 或其他线程时就会发生。 geti2() 得到的是main

Java中关键字volatile 和 synchronized 的作用和区别

邮差的信 提交于 2020-03-30 12:59:41
volatile是变量修饰符,而synchronized则是作用于一段代码或方法 ;如下三个get方法的代码: 1 int i1; 2 int geti1() {return i1;} 3 4 volatile int i2; 5 int geti2() {return i2;} 6 7 int i3; 8 synchronized int geti3() {return i3;} geti1() 得到存储在当前线程中i1的数值。多个线程有多个i1变量拷贝,而且这些i1之间可以相互不同。换句话说,另一个线程可能已经改变了它线程内的i1值,而这个值可以和当前线程中的i1值不相同。 在Java内存模型中,有main memory(主内存区域),这里存放了变量目前的“准确值”,每个线程也有自己的memory(例如寄存器)。为了性能,一个线程会在自己的memory中保存要访问的变量的副本。这样就会出现同一个变量在某个瞬间,在一个线程的memory中的值可能与另外一个线程memory的值,或者main memory的值不一致的情况。因此实际上存在一种可能:main memory的值i1值是1,线程1里的i1是2,线程2里的i1值是3,这在线程1和线程2都改变了他们各自的i1值,而且这个改变还没来得及传给main memory 或其他线程时就会发生。 geti2() 得到的是main

多线程中volatile关键字的作用

随声附和 提交于 2020-03-30 12:49:08
原文链接: https://blog.csdn.net/xuwentao37x/article/details/27804169 多线程的程序是出了名的难编写、难验证、难调试、难维护,这通常是件苦差事。不正确的多线程程序可能可以运行很多年也不出一点错,直到满足某些临界的条件时,才出现意想不到的奇怪错误。 不用说,编写多线程程序的程序员需要使用可能得到的所有帮助。这期专栏将专注于讨论竞争条件(race conditions)——这通常是多线程程序中各种麻烦的根源——深入了解它并提供一些工具来防止竞争。令人惊异的是,我们将让编译器尽其所能来帮助你做这些事。 仅仅一个不起眼的关键字。 尽管C和C++标准对于线程都明显的“保持沉默”,但它们以volatile关键字的形式,确实为多线程保留了一点特权。 就象大家更熟悉的const一样,volatile是一个类型修饰符(type modifier) 。它是被设计用来修饰被不同线程访问和修改的变量。如果没有volatile,基本上会导致这样的结果:要么无法编写多线程程序,要么编译器失去大量优化的机会。下面我们来一个个说明。 考虑下面的代码: 代码: class Gadget { public: void Wait() { while (!flag_) { Sleep(1000); // sleeps for 1000 milliseconds }

java内存模型与多线程

我们两清 提交于 2020-03-30 12:48:42
现代计算机,cpu在计算的时候,并不总是从内存读取数据,它的数据读取顺序优先级是:寄存器-高速缓存-内存,线程计算的时候,原始的数据来自内存,在 计算过程中,有些数据可能被频繁读取,这些数据被存储在寄存器和高速缓存中,当线程计算完后,这些缓存的数据在适当的时候应该写回内存,当多个线程同时读 写某个内存数据时,由于涉及数据的可见性、操作的有序性,所以就会产生多线程并发问题。 Java作为平台无关性语言,JLS(Java语言规范)定义了一个统一的内存管理模型 JMM (Java Memory Model),JMM屏蔽了底层平台内存管理细节,在多线程环境中必须解决可见性和有序性的问题。JMM规定了jvm有 主内存 (Main Memory)和 工作内存 (Working Memory) ,主内存存放程序中所有的类实例、静态数据等变量,是多个线程共享的,而工作内存存放的是该线程从主内存中拷贝过来的变量以及访问方法所取得的局部变量, 是每个线程私有的其他线程不能访问,每个线程对变量的操作都是以先从主内存将其拷贝到工作内存再对其进行操作的方式进行,多个线程之间不能直接互相传递数 据通信,只能通过共享变量来进行。 JLS定义了线程对主存的操作指令: read,load,use,assign,store,write 。这些行为是不可分解的原子操作,在使用上相互依赖,read

Java并发编程的艺术(六)happens-before

自闭症网瘾萝莉.ら 提交于 2020-03-30 11:53:14
1、happens-before是JMM最核心的概念,JSR-133使用happens-before来指定 两个操作之间的执行顺序 。 2、如果A happens-before B,那么: (1)对程序员来说:A的执行结果对B可见,并且A的执行顺序排在B之前。 (2)对编译器和处理器来说:不一定要按照程序顺序执行,在不改变程序执行结果(指 单线程 或 正确同步的多线程 )的前提下,允许重排序。 3、happens-before规则: (1) 程序顺序 规则:一个线程中的每个操作,happens-before于该线程中的任意后续操作。 (2) 监视器 规则:对一个锁的解锁,happens-before于随后对这个锁的加锁。 (3) volatile变量 规则:对一个volatile域的写,happens-before于任意后续对这个volatile域的读。 (4) 传递性 :如果A happens-before B,且B happens-before C,那么A happens-before C。 (5)start()规则:如果线程A执行操作ThreadB.start()(启动线程B),那么A线程的ThreadB.start()操作happens-before于线程B中的任意操作。 (6)join()规则:如果线程A执行操作ThreadB.join()并成功返回

mutable和volatile关键字

末鹿安然 提交于 2020-03-30 11:50:22
1.mutable 在C++中,mutable是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中,甚至结构体变量或者类对象为const,其mutable成员也可以被修改。mutable在类中只能够修饰 非静态数据成员 。 #include <iostream> using namespace std; class test { mutable int a; int b; public: test(int _a,int _b) :a(_a),b(_b){}; void fun() const //fun是const 函数,不能修改类的对象的数据成员,但由于a被mutable修饰,可以修改,但不能修改b { a += b; } void print() { cout << a << "," << b << endl; } }; 我们知道,如果类的成员函数不会改变对象的状态,那么这个成员函数一般会声明成const的。但是,有些时候,我们需要在const的函数里面修改一些跟类状态无关的数据成员,那么这个数据成员就应该被mutalbe来修饰。 2.volatile volatile原意是“易变的”,但这种解释简直有点误导人,应该解释为“直接存取原始内存地址”比较合适。“易变”是相对与普通变量而言其值存在编译器(优化功能

volatile修饰变量

[亡魂溺海] 提交于 2020-03-30 11:47:19
volatile 影响编译器编译的结果,指出, volatile 变量是随时可能发生变化的,与 volatile 变量有关的运算,不要进行编译优化,以免出错,( VC++ 在产生 release 版可执行码时会进行编译优化,加 volatile 关键字的变量有关的运算,将不进行编译优化。)。 例如: volatile int i=10; int j = i; ... int k = i; volatile 告诉编译器 i 是随时可能发生变化的,每次使用它的时候必须从 i 的地址中读取,因而编译器生成的可执行码会重新从 i 的地址读取数据放在 k 中。 而优化做法是,由于编译器发现两次从 i 读数据的代码之间的代码没有对 i 进行过操作,它会自动把上次读的数据放在 k 中。而不是重新从 i 里面读。这样以来,如果 i 是一个寄存器变量或者表示一个端口数据就容易出错,所以说 volatile 可以保证对特殊地址的稳定访问,不会出错。 /********************** 一个定义为 volatile 的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。 精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是 volatile 变量的几个例子: 1) 并行设备的硬件寄存器(如:状态寄存器) 2