首先,volatile
是 C 和 C++ 中的一个关键字,用于告诉编译器该变量是可以被其他线程修改的,从而避免了编译器进行一些针对该变量的优化,确保了内存中的正确性。
使用 volatile
的作用是使变量的访问和修改都在主内存中进行,而不是在寄存器或缓存中进行,以实现不同线程之间的可见性和互通性。例如,在多线程程序中,如果一个线程修改了一个变量的值,而另一个线程读取相同的变量的值,那么使用 volatile
可以确保这个值的正确传递,从而保证程序正确的执行。
下面是两条示例说明:
示例一
在以下示例代码中,当flag
变量不使用 volatile
修饰时会出现死循环的现象。因为flag
变量在一个线程中被修改了,但在另一个线程中无法共享。
#include <iostream>
#include <thread>
bool flag = false;
void modify_flag() {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
flag = true;
}
void read_flag() {
while (!flag) {
// 死循环,无法退出
}
std::cout << "flag is true." << std::endl;
}
int main() {
std::thread t1(modify_flag);
std::thread t2(read_flag);
t1.join();
t2.join();
return 0;
}
使用 volatile
修饰 flag
变量,就能正确地实现变量在两个线程之间的共享性:
#include <iostream>
#include <thread>
volatile bool flag = false;
void modify_flag() {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
flag = true;
}
void read_flag() {
while (!flag) {
// 循环等待
}
std::cout << "flag is true." << std::endl;
}
int main() {
std::thread t1(modify_flag);
std::thread t2(read_flag);
t1.join();
t2.join();
return 0;
}
示例二
以下示例说明了如何使用 volatile
关键字来实现单例模式。
class Singleton {
private:
static volatile Singleton* instance;
static std::mutex mtx;
Singleton() {};
public:
static Singleton* getInstance() {
if (instance == nullptr) {
std::lock_guard<std::mutex> lock(mtx);
if (instance == nullptr) {
instance = new Singleton();
}
}
return instance;
}
};
volatile Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;
int main() {
Singleton* s1 = Singleton::getInstance();
Singleton* s2 = Singleton::getInstance();
std::cout << (s1 == s2) << std::endl; // true
return 0;
}
由于 instance
变量需要在多个线程之间进行访问和修改,所以需要使用 volatile
关键字来修饰它。此外还需要使用锁保证单例的稳定性,这里使用了 std::mutex
。
以上是关于 volatile
关键字的使用攻略,通过这两个示例说明了它的作用和使用方法。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:volatile关键字的作用是什么? - Python技术站