Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 互斥操作函数参数是否应为“volatile”?_C_Multithreading_Mutex - Fatal编程技术网

C 互斥操作函数参数是否应为“volatile”?

C 互斥操作函数参数是否应为“volatile”?,c,multithreading,mutex,C,Multithreading,Mutex,我正在使用定制嵌入式实时操作系统,该系统具有一些自制线程和同步功能。互斥的实施方式与下文概述的方式类似: typedef int Mutex; #define MUTEX_ACQUIRED 1 #define MUTEX_RELEASED 0 bool AquireMutex(Mutex* pMutex) { bool Ret; // Assume atomic section here (implementation specific) if( *pMut

我正在使用定制嵌入式实时操作系统,该系统具有一些自制线程和同步功能。互斥的实施方式与下文概述的方式类似:

typedef int Mutex;
#define MUTEX_ACQUIRED    1
#define MUTEX_RELEASED    0

bool AquireMutex(Mutex* pMutex)
{
    bool Ret;
    // Assume atomic section here (implementation specific)
    if( *pMutex == MUTEX_RELEASED )
    {
         *pMutex = MUTEX_ACQUIRED;
         Ret = true;
    } 
    else
    {
         Ret = false;
    }
    // Atomic section end
    return Ret;
}

void ReleaseMutex(Mutex* pMutex)
{
    // Assume atomic section here (implementation specific)
    *pMutex = MUTEX_RELEASED;
    // end atomic section
}
让我们假设上述两个函数是原子函数(在实际实现中是原子函数,但实际实现与问题无关)

每一个线程都共享一些全局定义的
m
,并具有类似以下代码:

extern Mutex m;
// .............
while (!AquireMutex(&m)) ;
// Do stuff
ReleaseMutex(&m);
问题是关于线路:

while (!AquireMutex(&m)) ;
AquireMutex
是否会在每次迭代中实际进行评估?或者优化器会把它看作常量,因为它不会看到<代码> M < /代码>是如何改变的? 是否应使用
volatile
限定符来声明
AquireMutex

bool AquireMutex(volatile Mutex* pMutex);

答案取决于使用while循环的调用站点是否可以看到这些函数的实现。如果不是(调用站点只看到声明,定义在单独的源文件中),那么
volatile
关键字将不会改变任何内容。优化器完全不知道这个函数对参数做了什么,它是否有副作用等等,所以每个函数调用都会进行


另一方面,如果释放和获取互斥锁的函数是内联的,那么完整的实现在调用站点上是可见的,那么优化器可能会稍微“调整”一下。问题在于“complete”一词——即使您发布的代码是内联的,但关键部分开始和结束的代码可能不是。即使是这样,它也可能使用优化器无法理解的汇编语句。即使它是纯C,也可能访问一些易失性内存映射寄存器。任何这样的代码(调用外部函数、汇编语句、访问易失性内存)都会有效地阻止优化器消除所有调用,因为在这种情况下,优化器必须假设每个调用都有副作用=>
外部易失性互斥锁m?是的,这很有意义。我猜现在优化器无法跨翻译单元工作…@EugeneSh.-除非你使用LTO(;代表…?@EugeneSh.-这是链接时间优化,据说可以跨翻译单元进行优化。但不要担心这件事——如果有任何操作会产生副作用的话(例如带有汇编指令的关键部分代码或访问易失性内存映射寄存器),那么您仍然是安全的。酷..看起来我的编译器必须显式启用它,而不是..但很高兴知道