通过访问功能访问共享内存需要“volatile”吗? [英] Is `volatile` required for shared memory accessed via access function?

查看:274
本文介绍了通过访问功能访问共享内存需要“volatile”吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

[编辑]为了背景阅读,要清楚,这正是我在说的: volatile关键词简介

[edit] For background reading, and to be clear, this is what I am talking about: Introduction to the volatile keyword

在审查嵌入式系统代码时,我看到的最常见的错误之一是省略了易失性用于线程/中断共享数据。然而,我的问题是,当通过访问功能或成员函数访问变量时,是否安全不使用 volatile

When reviewing embedded systems code, one of the most common errors I see is the omission of volatile for thread/interrupt shared data. However my question is whether it is 'safe' not to use volatile when a variable is accessed via an access function or member function?

一个简单的例子;在以下代码中...

A simple example; in the following code...

volatile bool flag = false ;
void ThreadA()
{
    ...
    while (!flag)
    {
        // Wait
    }
    ...
}

interrupt void InterruptB()
{
    flag = true ;
} 

...变量标志必须是volatile的,以确保ThreadA中的读取没有被优化,但是如果标志是通过函数读取的,那么...

... the variable flag must be volatile to ensure that the read in ThreadA is not optimised out, however if the flag were read via a function thus...

volatile bool flag = false ;
bool ReadFlag() { return flag }
void ThreadA()
{
    ...
    while ( !ReadFlag() )
    {
        // Wait
    }
    ...
}

... 标志仍然需要变动?我意识到没有任何伤害,它是挥发性的,但我的关注是什么时候被省略,省略没有发现;这将是安全的吗?

... does flag still need to be volatile? I realise that there is no harm in it being volatile, but my concern is for when it is omitted and the omission is not spotted; will this be safe?

上面的例子是微不足道的;在真实的情况下(和我的问题的原因),我有一个类库包装一个RTOS,以便有一个抽象类cTask,任务对象派生自。这样的活动对象通常具有访问数据的成员函数,而不是可以在对象的任务上下文中修改,而是从其他上下文访问数据;那么这个数据是非常重要的吗?

The above example is trivial; in the real case (and the reason for my asking), I have a class library that wraps an RTOS such that there is an abstract class cTask that task objects are derived from. Such "active" objects typically have member functions that access data than may be modified in the object's task context but accessed from other contexts; is it critical then that such data is declared volatile?

我真的很感兴趣这些数据的保证,而不是一个实用的编译器可能做。我可以测试一些编译器,发现他们从来没有通过访问器优化读取,但是有一天会发现编译器或编译器设置使得这个假设不真实。我可以想象,例如,如果函数是内联的,这样的优化对于编译器来说将是微不足道的,因为它与直接读取没有什么不同。

I am really interested in what is guaranteed about such data rather than what a practical compiler might do. I may test a number of compilers and find that they never optimise out a read through an accessor, but then one day find a compiler or a compiler setting that makes this assumption untrue. I could imagine for example that if the function were in-lined, such an optimisation would be trivial for a compiler because it would be no different than a direct read.

推荐答案

我对C99的阅读是,除非您指定 volatile ,那么实际访问变量的方式和时间是实现定义的。如果您指定 volatile 限定符,则代码必须根据抽象机的规则工作。

My reading of C99 is that unless you specify volatile, how and when the variable is actually accessed is implementation defined. If you specify volatile qualifier then code must work according to the rules of an abstract machine.

标准中的相关部分是: 6.7.3类型限定符(易失性描述)和 5.1.2.3程序执行(抽象机器定义)。

Relevant parts in the standard are: 6.7.3 Type qualifiers (volatile description) and 5.1.2.3 Program execution (the abstract machine definition).

现在有一段时间,我知道许多编译器实际上具有启发式方法来检测一个变量应该重新读取的情况,何时可以使用缓存副本。易失性使得编译器清楚,对变量的每次访问应该实际上是对存储器的访问。没有变化,似乎编译器不用重新读取该变量。

For some time now I know that many compilers actually have heuristics to detect cases when a variable should be reread again and when it is okay to use a cached copy. Volatile makes it clear to the compiler that every access to the variable should be actually an access to the memory. Without volatile it seems compiler is free to never reread the variable.

并且BTW在函数中包含访问并不会改变,因为即使没有 inline 可能在当前编译单元中的编译器仍然内联。

And BTW wrapping the access in a function doesn't change that since a function even without inline might be still inlined by the compiler within the current compilation unit.

PS对于C ++,可能值得检查前者基于的C89。我手头没有C89。

P.S. For C++ probably it is worth checking the C89 which the former is based on. I do not have the C89 at hand.

这篇关于通过访问功能访问共享内存需要“volatile”吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆