linux C 中的volatile使用

一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的 值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在 寄存器里的备份。下面是volatile变量的几个例子:

1). 并行设备的硬件寄存器(如:状态寄存器)

2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)

3). 多线程应用中被几 个任务共享的变量

回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员 的最基本的问题。嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所用这些都要求volatile变量。不 懂得volatile内容将会带来灾难。

假设被面试者正确地回答了这是问题(嗯,怀疑这否会是这样),我将 稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重要性。

1). 一个参数既可以是const还可 以是volatile吗?解释为什么。

2). 一个指针可以是volatile 吗?解释为什么。

3). 下面的函数有 什么错误:

    int square(volatile int *ptr)

    {

         return *ptr * *ptr;

    }

下面是答案:

1). 是的。一个例 子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改 它。

2). 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。

3). 这段代码的有个恶作剧。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个 volatile型参数,编译器将产生类似下面的代码:

int square(volatile int *ptr)

   {

    int a,b;

    a = *ptr;

    b = *ptr;

    return a * b;

}

由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段 代码可能返不是你所期望的平方值!正确的代码如下:

long square(volatile int *ptr)

    {

       int a;

       a = *ptr;

       return a * a;

}

时间: 2024-08-03 03:35:06

linux C 中的volatile使用的相关文章

linux C 中的volatile使用【转】

转自:http://blog.csdn.net/sukhoi27smk/article/details/38020583 一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了.精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份.下面是volatile变量的几个例子:     1). 并行设备的硬件寄存器(如:状态寄存器)     2). 一个中断服务子程序中会访问到的非自动变量(Non-au

linux内核 访问外设-Linux驱动中访问外设端口的outb为什么不是访问内存空间

问题描述 Linux驱动中访问外设端口的outb为什么不是访问内存空间 原文如下面,其中第一个宏的意思不是把值v赋给了内存地址为a的内存空间吗,为什么是访问outb是往外设端口写数据的? 在linux的驱动程序中,都会使用大量的outb.outw.inb.inw等等宏来访问硬件或寄存器.这些宏的定义都在相应处理器体系下的include/asm目录下的io.h中定义.追究下去,这些宏最终就是一个volatile变量的的赋值: #define arch_putb(v,a) (*(volatile u

Linux内核中的内存管理浅谈

 [十月往昔]--Linux内核中的内存管理浅谈 为什么要叫做"十月往昔"呢?是为了纪念我的原博客. 不知道为什么,突然想来一个新的开始--而那个博客存活至今刚好十个月,也有十个月里的文档. 十月往昔,总有一些觉得珍贵的,所以搬迁到这里来. 而这篇文章是在09.04.20-09.04.21里写的. Jason Lee   ------------–cut-line   1.基本框架(此处主要谈页式内存管理) 4G是一个比较敏感的字眼,早些日子,大多数机器(或者说操作系统)支持的内存上限

经典]Linux内核中ioremap映射的透彻理解【转】

转自:http://blog.csdn.net/lanyang123456/article/details/7403514 几乎每一种外设都是通过读写设备上的寄存器来进行的,通常包括控制寄存器.状态寄存器和数据寄存器三大类,外设的寄存器通常被连续地编址.根据CPU体系结构的不同,CPU对IO端口的编址方式有两种: (1)I/O映射方式(I/O-mapped) 典型地,如X86处理器为外设专门实现了一个单独的地址空间,称为"I/O地址空间"或者"I/O端口空间",CP

Linux内核中的jiffies及其作用介绍及jiffies等相关函数详解

在LINUX的时钟中断中涉及至二个全局变量一个是xtime,它是timeval数据结构变量,另一个则是jiffies,首先看timeval结构struct timeval{time_t tv_sec; /***second***/susecond_t tv_usec;/***microsecond***/}到底microsecond是毫秒还是微秒?? 1秒=1000毫秒(3个零),1秒=1000 000微秒(6个零),1秒=1000 000 000纳秒(9个零),1秒=1000 000 000

Linux内核中的中断栈与内核栈的补充说明【转】

转自:http://blog.chinaunix.net/uid-12461657-id-3487463.html 原文地址:Linux内核中的中断栈与内核栈的补充说明 作者:MagicBoy2010   中断栈与内核栈的话题更多地属于内核的范畴,所以在<深入Linux设备驱动程序内核机制>第5章"中断处理"当中,基本上没怎么涉及到上述内容,只是在5.4节有些许的文字讨论中断栈在中断嵌套情形下可能的溢出问题. 本贴在这个基础上对内核栈与中断栈的话题做些补充,讨论基于x86

基本数据结构和算法在Linux内核中使用

基本数据结构和算法在Linux内核中使用 gaufunga day ago 搬运工 Linux内核(源代码的链接在github). 1.链表.双向链表.无锁链表. 2.B+ 树,这是一些你无法在教科书上找到的说明. 一个相对简单的B+树的实现.我把它作为一个学习练习来帮助理解B+树是如何工作的.这同样也被证明是有用的. ... 一个在教科书中并不常见的技巧.最小的值在右侧而不是在左侧.所有在一个节点里用到的槽都在左侧,所有没有用到的槽包含了空值(NUL).大多数操作只简单地遍历所有的槽一次并在第

linux虚拟机-linux光盘中加入自己的rpm,重新制作成iso后,虚拟机启动少了几个rpm包

问题描述 linux光盘中加入自己的rpm,重新制作成iso后,虚拟机启动少了几个rpm包 大体步骤就是先把光盘文件考到计算机中,然后在Package中加入自己的包,createrepo后制作镜像,虚拟机启动后用命令查发现少了几个包,问了项目老大,老大让我自己改依赖关系文件,自己摸索着改后发现启动不了了,大神请帮忙分析分析.

linux系统中root用户不能登录怎么办?

问题描述 linux系统中root用户不能登录怎么办? 自从我更改了Linux系统的IP地址,root用户就不能登录了,root用户登录提示"鉴定故障".普通用户可以登录,能用su命令登录root用户,但是不能直接登录. 解决方案 如果没有给ROOT设置密码,就用普通用户登录,没有普通用户这是不可能的登录进入终端,直接输入 sudo passwd root输入普通用户密码输入你要设置的root密码重复root密码这样用root就行了 解决方案二: 终端输入:sudo gedit /us