让我们假设它是一些ARM Controller 的嵌入式开发。假设我们有一些变量,它可以从中断或“mainThread”分配 - (它是“主循环”还是 RTOS 线程)。在C世界volatile
在这种情况下应该使用关键字,代码可能如下所示:
/* Some subsystem .C file */
static volatile uint8_t state;
void on_main_thread(void) {
state = 1; /* Changing state in this context */
}
void on_interrupt(void) {
state = 0; /* Changing state from interrupt */
}
uint8_t get_state(void) {
return state; /* Getting the state in whatever context */
}
volatile
在这种情况下,关键字是必不可少的。现在我们公司把一些代码改写成C++,同样的子系统例子是这样的(我这里用enum来强调这个问题)class SomeSubsystem
{
public:
enum class States
{
Off,
Idle,
Up,
Down,
};
States getState() const { return mState; }
void onMainThread(void) {
mState = States::Idle; // Changing state in this context
}
// Somehow this function is called from the interrupt
void onInterrupt(void) {
mState = States::Up; // Changing state from interrupt
}
private:
States mState; // <-- Here! Volatile?
//...
};
现在
States mState
应该是可变的,因为它在不同的上下文之间共享。但如果将其设置为 volatile... 那么 volatile
就像 C++ 类的瘟疫一样,你必须 volatile 周围的一切。赞 volatile enum class States
, getState() volatile
等等,这对我来说不好看(我错了吗?)所以。在 C++ 中处理这种情况的正确方法是什么?
附言我会尝试将“这种情况”定义为:“可能使用来自不同上下文(如中断和正常代码执行)的类成员”
最佳答案
如果您的程序中只需要 SomeSubsystem 的单个实例(我假设根据您发布的 c 代码进行假设),这可能会起作用。
如果您需要多个实例,那么也许您可以将 mState 修改为 States 数组或一些类似的结构。
class SomeSubsystem
{
public:
enum class States
{
Off,
Idle,
Up,
Down,
};
States getState() const { return mState; }
void onMainThread(void) {
mState = States::Idle; // Changing state in this context
}
// Somehow this function is called from the interrupt
void onInterrupt(void) {
mState = States::Up; // Changing state from interrupt
}
// Make mState public in order to access it from the rest of your code
// Otherwise, keep it private and create static set/get functions
public:
static volatile States mState; // <-- Here! Volatile?
//...
};
然后在某处定义 mState(例如在 SomeSubsystem.cpp 中)
volatile SomeSubsystem::States SomeSubsystem::mState = SomeSubsystem::States::Off;
现在您可以像这样从代码中的任何位置访问 mState
SomeSubsystem::mState = SomeSubsystem::States::Off;
关于c++ - 使用 volatile 类成员进行中断处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38610847/