volatile关键字

1.volatile关键字是什么

cc++中,volatile关键字用于告诉编译器,变量的值可能会在程序执行期间被意外地改变,因此编译器不应该进行优化。

volatile int i = 10;
volatile int i = 11;
volatile int i = 12;

通过对变量加入volatile关键字特征修饰符可以保证变量i在程序运行过程中每条指令都被正确地执行。

2.volatile的作用

2.1 防止被编译器优化

编译器在编译代码时会对代码优化提高程序的执行效率。编译期可能会将一些常量或者变量的值缓存到寄存器中以便快速访问。

当程序处于多线程编程和信号处理的场景下时,变量的值可能被意外地改变导致程序出现错误。

int i = 0;
while(i < 10){
	std::cout << "" << std::endl;
	i++;
}

虽然在循环中,变量i的值确实会被更新,但是编译器可能会把i的值缓存到寄存器中,导致循环无法正常退出。
通过引入volatile关键字可以解决这一问题。

volatile int i = 0;
while(i < 10){
	std::cout << "" << std::endl;
	i++;
}

在这个代码中,使用volatile关键字告诉编译器,变量count的值可能被意外地改变,因此编译器不应该对该变量进行优化。

2.2 多线程同步

在多线程编程中,多个线程可能同时访问同一个变量。如果变量的值被缓存到寄存器中,就会导致线程之间的数据不一致。

volatile int count = 0;
pthread_t threads[10];
void* thread_func(void* arg) {    
	while (count < 10) {        
		printf("%d\n", count);        
		count++;
	}    
	return NULL;
}
void main() 
{    
	for (int i = 0; i < 10; i++) 
	{
	 	pthread_create(&threads[i], NULL, thread_func, NULL);    
	}    
	for (int i = 0; i < 10; i++) 
	{
		pthread_join(threads[i], NULL);    
	}    
	return;
}

当前代码启动了 10 个线程,每个线程都会访问变量 count 并对其进行更新。如果变量 count 的值被缓存到寄存器中,就会导致线程之间的数据不一致。
因此需要使用volatile关键字告诉编译器,变量count的值可能被意外地改变,因此编译器不应该对变量进行优化。

2.3 对寄存器的访问

在嵌入式编程中,因为需要经常访问硬件寄存器,由于硬件寄存器的值可能会被意外地改变,因此需要使用volatile关键字来告诉编译器,变量的值可能会被意外地改变。

#define GPIO_BASE 0x12345678
volatile unsigned int* gpio = (volatile unsigned int*)GPIO_BASE;
void set_gpio(unsigned int value) 
{    
	*gpio = value;
}
unsigned int get_gpio() 
{    
	return *gpio;
}

这段代码中,定义了一个指针gpio指向硬件寄存器的地址,由于硬件寄存器的值可能被意外改变,因此使用volatile关键字来告诉编译器,该值在运行期间可能被动态改变多次,不要进行优化。

3.volatile关键字的注意事项

①在C语言中volatile关键字只能用于变量,不能用于函数、结构体。
②在C语言中volatile关键字不能用于指针类型,因为指针类型本身就是一个地址,没有值可以被缓存。
③在C语言中volatile关键字不能保证线程安全,因为它只能防止编译器优化,不能保证多个线程之间的数据一致性。

  • 参考示例

stm32函数库底层的寄存器定义就是加了volatile的
请添加图片描述
请添加图片描述

参考链接

https://baijiahao.baidu.com/s?id=1766831734273806604&wfr=spider&for=pc
【C语言volatile关键字详解】https://blog.csdn.net/u010134355/article/details/125058164

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值