关于(非易失性和优化编译器的问题

问题描述 投票:1回答:1

我有以下C代码:

/* the memory entry points to can be changed from another thread but 
 * it is not declared volatile */
struct myentry *entry;

bool isready(void)
{
    return entry->status == 1; 
}

bool isready2(int idx)
{
    struct myentry *x = entry + idx;        
    return x->status == 1; 
}

int main(void) {
    /* busy loop */
    while (!isready()) 
        ; 
    while (!isready2(5)) 
        ; 
}

正如我在评论中指出的,即使条目指向的数组可以从另一个线程更改(或实际上甚至直接从内核空间更改),该条目也被声明为易失性[]。以上代码不正确/不安全吗?我的想法是,不能在isready,isready2的主体中执行优化,并且由于我从main内反复执行函数调用,因此应在每次调用时读取适当的内存位置。

另一方面,编译器可以内联这些函数。是否有可能以导致发生单个读取(因此导致无限循环)而不是多个读取(即使这些读取来自加载/存储缓冲区的方式)的方式进行?] >>

还有第二个问题。是否可以通过仅在某些特定位置强制转换为volatile来防止编译器进行优化?

void func(void) { entry->status = 1; while (((volatile struct myentry *) entry)->status != 2) ; }

谢谢。

我有以下C代码:/ *可以从另一个线程更改的内存入口点,但是*它没有声明为volatile * / struct myentry * entry; bool isready(void){返回条目-> ...

如果内存entry指向可以被另一个线程修改,则程序具有

数据争用

,因此行为未定义。即使使用volatile,也是如此。要使一个变量被多个线程并发访问,在ISO C11中,它必须是atomic type或受到正确同步的保护。

如果使用较旧的标准修订版,那么标准不提供多线程保证,因此您受制于编译器的任何特有行为。

如果使用POSIX线程,则没有可移植的原子操作,但它确实定义了同步原语。

另请参见:

c multithreading volatile
1个回答
0
投票
如果内存entry指向可以被另一个线程修改,则程序具有

数据争用

© www.soinside.com 2019 - 2024. All rights reserved.