gpt4 book ai didi

c - 在这种情况下正确使用 'volatile' (C)?

转载 作者:行者123 更新时间:2023-12-04 00:03:37 25 4
gpt4 key购买 nike

我有一个包含多个指针的结构。这些指针可以被几个不同的线程改变。这些线程通过更改指针来更新结构,使其指向另一个内存位置,它们从不更改指向的值。根据我对 volatile 的理解,将结构中的这些指针声明为 volatile 是有意义的。

读取/更新这些指针的线程是这样工作的:

  • 复制指针,只使用我们的副本,这样如果原始更改我们不会在过程中途突然使用新指针。
  • 根据我们的副本指向的值创建一个新指针。
  • 使用原子比较+交换将旧指针替换为新指针,除非另一个线程已经更新了它。

我遇到的问题是,当我复制指针时,我收到警告:

warning: initialization discards ‘volatile’ qualifier from pointer target type

编译后的代码似乎工作正常,但警告让我很困扰。我是否错误地使用了 volatile?假设我对 volatile 的使用没问题,我该如何删除警告?我不想将 volatile 添加到复制指针的声明中,没有其他线程会更新我们的副本,所以它确实不是 volatile。它仅在读/写结构时易变。

这是一些简单演示我的问题的演示代码,我正在使用的实际代码要好得多,但也太大而无法发布。存在明显的内存泄漏,暂时忽略它我的真实用例正确跟踪和管理内存。我只关心这个问题的“易变性”,我不在我的演示中寻找要解决的错误。

gcc -std=gnu99 -pthread test.c && ./a.out
test.c: In function ‘the_thread’:
test.c:22:25: warning: initialization discards ‘volatile’ qualifier from pointer target type [enabled by default]

代码:

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>

typedef struct {
volatile int *i;
} thing;

void init( thing *t ) {
t->i = malloc( sizeof( int ));
*(t->i) = 1;
}

void *the_thread( void *args ) {
thing *t = args;

for ( int i = 0; i < 100; i++ ) {
// This generates the 'volatile' warning. But I don't want to make
// *copy volatile since no other threads will ever change 'copy'.
// Is this incorrect usage, or do I just need to do something to remove
// the warning?
int *copy = t->i;

int *new = malloc( sizeof( int ));
*new = (*copy) + 1;

// Glaring memory leak as old x becomes unreachable, this is a demo,
// the real program this is for has the issue solved.
// We do not care if it succeeds or fails to swap for this demo.
__sync_bool_compare_and_swap( &(t->i), copy, new );
}
}

int main() {
thing t;
init( &t );

pthread_t a;
pthread_t b;

pthread_create( &a, NULL, the_thread, &t );
pthread_create( &b, NULL, the_thread, &t );

pthread_join( a, NULL );
pthread_join( b, NULL );

return 0;
}

最佳答案

这是因为 volatile int * 不是“指向 int 的易失指针”,而是“指向 volatile int 的指针”。比较const char *a = "foo";,那是指向常量字符数据的指针,不是常量指针。

因此,在您的情况下,我认为 thing 指针应该是 volatile,因为其中的字段可以“随机”更改(从一个线程的角度来看).您还可以(正如您在评论中所说)移动 volatile 使其成为结构中的 int * volatile i;

您(当然)可以始终使用 cdecl也可以获得即时帮助来解决这些问题。

关于c - 在这种情况下正确使用 'volatile' (C)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15413766/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com