一个定义为volatile的变量说明可能会被意想不到地改变,这样,编译器就不会假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器中的备份。
volatile主要应用于以下3种情况下:
1.嵌入式设备I/O读写
嵌入式设备I/O(例如ARM等)采用统一编址方式,即从存储空间中划出一部分地址给I/O端口。在进行I/O读写时,需要用volatile修饰。
例如:
读数据:int a = *((volatile int *) 0x7F008000);
写数据:*((volatile int *) 0x7F008000) = 0x12345678;
#define GPACON *((volatile int *) 0x7F008000)
int a = GPACON;
GPACON = 0x123456;
2.嵌入汇编代码不让优化
例如用汇编代码实现memcpy。(具体操作省略。。)
int memcpy(char *dest, char *src, int size)
{
__asm__ __volatile__ (“ “);
//asm volatile (“ “);
}
3.多线程使用同一变量
例如我们利用全局变量制作一个锁,实现线程间的同步。
#include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <string.h>
typedef volatile int LOCK; LOCK var1 = 0; //int var1 = 0;
int sum = 0;
void lock(void) { retry: if(var1 == 0) var1 = 1; else goto retry; }
void unlock(void) { var1 = 0; }
void * t1(void *arg) { printf("in t1: var1 = %d\n", var1); lock(); sum += 10; sleep(1); printf("in t1: sum = %d\n", sum); unlock(); return NULL; }
void * t2(void *arg) { printf("in t2: var1 = %d\n", var1); lock(); sum += 50; sleep(1); printf("in t2: sum = %d\n", sum); unlock(); return NULL; }
int main(void) { int ret; pthread_t tid; ret = pthread_create(&tid, NULL, t1, NULL); if(ret == -1){ printf("pthread_create:%s\n", strerror(ret)); exit(1); } ret = pthread_create(&tid, NULL, t2, NULL); if(ret == -1){ printf("pthread_create:%s\n", strerror(ret)); exit(1); } sleep(3); pthread_exit(NULL); }
|
用volatile变量作为锁,运行结果为:
zx@zhangxu:~/lianxi$ gcc -o test lock.c -lpthread
zx@zhangxu:~/lianxi$ ./test
in t1: var1 = 0
in t2: var1 = 1
in t1: sum = 10
in t2: sum = 60
|
阅读(1493) | 评论(0) | 转发(0) |