volatile

c语言const、volatile问题小结

≡放荡痞女 提交于 2020-03-30 11:45:57
之前百度面试的时候被volatile虐了,内核中很多地方也会用到,这个面试的时候出现概率太大了,所以搜集了一些结果供大家参考,大部分是百度到的,说得挺明确的,以后读代码的时候遇到了再更新。 百度知道有人提如下问题: #include "stdio.h" int main(void){ const char i = 1; char * j = (char *)&i; printf("%d,%d,%p,%p\n",i,*j,&i,j);//1,1 *j = 2; printf("%d,%d,%p,%p\n",i,*j,&i,j);//1,2 *j = 3; printf("%d,%d,%p,%p\n",i,*j,&i,j);//1,3 } 为什么i没有改变呢,各位运行也会发现,他们的地址都是一样的。 醉了,我debug的时候,i也是随着j改变的,但是输出时,i就变成1了。希望各位能够从编译的角度上说一下这个问题。 我对答案有稍微修改,对比vc编译结果差不多所以就引用别人的图了 1.这是有const修饰与无const修饰的汇编代码 变量i存储在eax寄存器中,有const修改表达寄存器的值不允许被修改 第22行的时候,对*j=2;赋值时,有const修饰的会对edx进行操作 而没有const进行修饰的就是直接对eax进行操作. 至于编译器调试模式下 , 看见的 i 的值变成 2,

Tiny4412之重力感应器驱动

冷暖自知 提交于 2020-03-30 02:07:17
一:Tiny4412 裸板重力感应驱动编写   整个编写过程大概分为如下几步:   (1)在底板上找到重力感应器的所在位置,找到芯片型号(我用的板子上重力感应器芯片型号为: MMA7660FC )   (2)通过型号查看重力感应器电路图,了解每个引脚的功能   (3)找到引脚对应的网标(EINT,SDL,SCL)配置其相应的gpio口   (4)配置芯片相关寄存器   (5)使用I2C来读取重力感应器相应寄存器的值   下面是整个驱动的简单流程图: 通过看底板我们知道了重力感应器的控制芯片型号为: MMA7660FC,接下来我们就在看看改芯片的电路图(如下): 由上图我们可以看出它的外部中断XEINT25,用到的i2c总线为SDA3、SCL3 通过网标我们可以看到它是怎么连接到核心板上的(soc) 由上图可知,XEINT25、I2CSDA3、SCL3所对应的gpio分别为GPA1_2、GPA1_3、GPX3_1,之后我们就可以配置gpio口为相应的功能 通过datasheet我们可以找到它的外部中断号为64,如下图: 简单了解了mma7660的电路图之后我们就需要看芯片的datasheet,了解里面寄存器的配置及功能 首先看一下整个芯片与我们核心板的连接图: 由上图我们可以看出,芯片连接到我们核心板(soc)的总共为三根线:INT( 中断信号),SDA、SCL

并发编程面试题

蹲街弑〆低调 提交于 2020-03-29 18:32:53
1.进程和线程还有协程之间的关系   进程:     进程简单理解就是我们平常使用的程序,如QQ,浏览器,网盘等。进程拥有自己独立的内存空间地址,     拥有一个以上的线程。   线程:     线程可以理解为轻量级的进程,是程序执行的最小单元。在某个进程启动后,会默认产生一个主线程,     主线程可以创建多个子线程,   协成:     协成,又称微线程,纤程。协成是一个线程执行,但执行有点像多线程,协成的执行效率极高     简单点说协成是进程和 线程的升级版,进程喝 线程都面临着内内核态和用户态的切换问题而     耗费许多切换时间 ,而且协成就是用户自己控制切换的时机,不再需要 陷入系统的内核态。   一个程序至少有一个进程 ,一个进项至少有一个线程。线程不能独立执行,必须依存在进程中。   协成,应用程序级别(而非操作系统)控制切换,以此来提升 效率。 2.并发和并行之间的区别   并行(parallel):         指在同一时刻,有多条指令在多个处理器上同时执行。所以无论从微观还是宏观 来看         二者都是一起执行的。            小结:     当系统有一个以上 CPU 时,则线程的操作有可能非并发。当一个 CPU 执行一个线程时,另一个      CPU 可以执行另一个线程,两个线程互不抢占 CPU 资源,可以同时进行

多线程之wait,notify,volatile,synchronized,sleep

浪尽此生 提交于 2020-03-27 17:32:08
  最近在学习多线程,现在进行总结一下吧。首先要了解一下以下几个名词。   (1)wait:当线程调用wait()方法时,当前该线程会进入阻塞状态,且 释放锁 ,使用wait方法的时候, 必须配合synchronized使用 。   (2)notify:当线程调用notify()方法时,会唤醒一个处于等待该对象锁的线程, 不释放锁 ,使用notify方法的时候, 必须配合synchronized使用 。   (3)sleep:当线程调用sleep()方法时,会让出CPU执行权, 不释放锁 。当指定的时间到了后,会自动恢复运行状态。   (4)volatile:可见性,它修饰的成员变量在每次被线程访问时,都强迫从内存中重读该成员变量的值;而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存,这样在任何时刻两个不同线程总是看到某一成员变量的同一个值,这就是保证了可见性。( 当多个线程操作同一个成员变量的时候,为了提高效率,JVM为每个线程单独复制了一份 ,这样会导致各个线程读取的数据出现脏数据,所以使用volatile关键字可以解决脏数据问题)。   (5)synchronized:synchronized为一段操作或内存进行加锁,它具有互斥性。当线程要操作被synchronized修饰的内存或操作时, 必须首先获得锁才能进行后续操作

试题

牧云@^-^@ 提交于 2020-03-27 03:29:55
讲一讲并行和并发 进程的线程的区别 进程是资源分配的最小单位,线程是程序执行的最小单位。 进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。 线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。不过如何处理好同步与互斥是编写多线程程序的难点。 但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。 进程间通信的有哪几种方式 管道(Pipe)及有名管道(named pipe): 信号量 共享内存 信号(Signal) 报文(Message)队列(消息队列) 套接字 线程间资源可以共享吗,进程间呢 Java并发,说一说了解哪些,volatie个synchronized的 volatile本质是告诉JVM当前变量在寄存器中的值是不确定的,需要从主存中读取。synchronized则是锁定当前变量,只有当前线程可以访问该变量,其它线程被阻塞。 volatile仅能使用在变量级别,synchronized则可以使用在变量、方法。

Java 反射相关整理

╄→гoц情女王★ 提交于 2020-03-26 19:04:42
1. Class 类 Class 是一个类,封装了当前对象所对应的类的信息,一个类中有属性,方法,构造器等。 对于每个类而言,JRE 都为其保留一个不变的 Class 类型的对象。一个 Class 对象包含了特定某个类的有关信息。 Class 对象只能由系统建立对象,一个类(而不是一个对象)在 Java 虚拟机中只会有一个 Class 实例。 Class 对象的由来是将 class 文件读入内存,并为之创建一个 Class 对象。 获取 Class 类对象的三种方法 使用 Class.forName 静态方法,当知道类的全路径名时,可以使用该方法获取 Class 类对象。 Class clz = Class.forName("java.lang.String"); 使用 .class 方法,这种方法适合在编译前就知道操作的 Class。 Class clz = String.class; 使用类对象的 getClass() 方法。 String str = new String("Hello"); Class clz = str.getClass(); Class 类的常用方法 方法名 功能说明 static Class forName(String name) 返回指定类名 name 的 Class 对象。 Object newInstance() 调用缺省构造函数,返回该

JAVA反射原理

馋奶兔 提交于 2020-03-25 12:18:02
什么是反射? 反射,一种计算机处理方式。是程序可以访问、检测和修改它本身状态或行为的一种能力。java反射使得我们可以在程序运行时动态加载一个类,动态获取类的基本信息和定义的方法,构造函数,域等。除了检阅类信息外,还可以动态创建类的实例,执行类实例的方法,获取类实例的域值。反射使java这种静态语言有了动态的特性。 类的加载 java反射机制是围绕Class类展开的,在深入java反射原理之前,需要对类加载机制有一个大致的了解。jvm使用ClassLoader将字节码文件(class文件)加载到方法区内存中: Class clazz = ClassLoader.getSystemClassLoader().loadClass("com.mypackage.MyClass"); 可见ClassLoader根据类的完全限定名加载类并返回了一个Class对象,而java反射的所有起源都是从这个class类开始的。 ReflectionData 为了提高反射的性能,缓存显然是必须的。class类内部有一个useCaches静态变量来标记是否使用缓存,这个值可以通过外部配置项sun.reflect.noCaches进行开关。class类内部提供了一个ReflectionData内部类用来存放反射数据的缓存,并声明了一个reflectionData域,由于稍后进行按需延迟加载并缓存

volatile 手摸手带你解析

不打扰是莪最后的温柔 提交于 2020-03-25 11:01:03
前言 volatile 是 Java 里的一个重要的指令,它是由 Java 虚拟机里提供的一个轻量级的同步机制。一个共享变量声明为 volatile 后,特别是在多线程操作时,正确使用 volatile 变量,就要掌握好其原理。 特性 volatile 具有 可见性 和 有序性 的特性,同时,对 volatile 修饰的变量进行单个读写操作是具有 原子性 。 这几个特性到底是什么意思呢? 可见性: 当一个线程更新了 volatile 修饰的共享变量,那么任意其他线程都能知道这个变量最后修改的值。简单的说,就是多线程运行时,一个线程修改 volatile 共享变量后,其他线程获取值时,一定都是这个修改后的值。 有序性: 一个线程中的操作,相对于自身,都是有序的,Java 内存模型会限制编译器重排序和处理器重排序。意思就会说 volatile 内存语义单个线程中是串行的语义。 原子性: 多线程操作中,非复合操作单个 volatile 的读写是具有原子性的。 可见性 可见性是在多线程中保证共享变量的数据有效,接下来我们通过有 volatile 修饰的变量和无 volatile 修饰的变量代码的执行结果来做对比分析。 无 volatile 修饰变量 以下是没有 volatile 修饰变量代码,通过创建两个线程,来验证 flag 被其中一个线程修改后的执行情况。 /** * Created

Tiny4412裸机程序,按键检测

落爺英雄遲暮 提交于 2020-03-25 08:55:53
3 月,跳不动了?>>> 一、控制原理说明 先看一下原理图: 首先把按键对应的GPIO设置为输入模式,修改GPX3CON寄存器(板子不同,可能对应的GPIO管脚不同),通过上图可知当没有按下按键时,对应的GPIO状态为高电平,当有按键被按下时,对应的GPIO变为低,我们在程序一直检测这几个GPIO状态即可。 二、程序说明 其中Start.s文件同上一个实验完全相同;链接脚本key.lds的内容和led.lds完全相同,只把名字改了改;Makefile的内容也大部分一样,也只是改了改里边文件的名字,key.c的文件需要重新编写,代码如下: /* * 程序说明 * 一上电,4个LED全亮,当某个按键被按下,则对应的LED熄灭(可同时按下多个键) * 对应关系:KEY1-LED1,KEY2-LED2,KEY3-LED3,KEY4-LED4 */ //按键对应的GPIO #define GPX3CON (*(volatile unsigned int *)0x11000C60) #define GPX3DAT (*(volatile unsigned int *)0x11000C64) //LED对应的GPIO #define GPM4CON (*(volatile unsigned int *)0x110002E0) #define GPM4DAT (*(volatile

java中volatile关键字的含义

主宰稳场 提交于 2020-03-24 12:01:31
From: http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html 在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉。 Java语言是支持多线程的,为了解决线程并发的问题,在语言内部引入了 同步块 和 volatile 关键字机制。 synchronized 同步块大家都比较熟悉,通过 synchronized 关键字来实现,所有加上synchronized 和 块语句,在多线程访问的时候,同一时刻只能有一个线程能够用 synchronized 修饰的方法 或者 代码块。 volatile 用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值。volatile很容易被误用,用来进行原子性操作。 下面看一个例子,我们实现一个计数器,每次线程启动的时候,会调用计数器inc方法,对计数器进行加一 执行环境——jdk版本:jdk1.6.0_31 ,内存 :3G cpu:x86 2.4G 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public class Counter