我有一个结构,持有几个指针。这些指针可以被几个不同的线程改变。这些线程通过更改指针来更新结构,以便它指向另一个内存位置,它们永远不会更改指向的值。根据我对易失性的理解,将结构中的这些指针声明为volatile是有意义的。在这种情况下正确使用'volatile'(C)?
读/更新这些指针的线程的工作是这样的:
- 复制指针,只能用我们的副本,如果原来的变化,我们不会突然半途过程中使用的新的方式。
- 根据我们的副本指向的值创建一个新的指针。
- 使用原子比较+交换替换旧的指针与新的,除非另一个线程已经更新它。
我打的问题是,当我让我的指针的副本,我得到一个警告:
警告:初始化抛弃“挥发”指针目标类型的限定词
编译的代码似乎工作正常,但警告困扰我。我是否正确使用volatile?假设我使用volatile是好的,我该如何删除警告?我不想将volatile写入复制指针的声明中,其他线程都不会更新我们的副本,所以它实际上不会变化。它在读取/写入结构时唯一不稳定。
下面是一些简单演示我的问题的演示代码,我使用的实际代码更好,但也太大而无法发布。有一个明显的内存泄漏,现在忽略它我真正的用例正确地跟踪和管理内存。我只关心这个问题的'volatile',我没有在我的演示中寻找bug来解决。
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;
}
嗯,做更多的研究,不应该在结构中实际使用'int * volatile i'吗?这似乎是我用来使指针本身不稳定。也做出改变消除了我的警告......但我想确定它是如何工作的我认为它的确如此...... – Exodist 2013-03-14 16:04:10
是不是因为他将指针分配给非易失性int时将volatile指针分配给非易失性int复制?用法应该是int copy = *(t-> i);? – tinman 2013-03-14 20:17:33
@tinman如果我在处理整数,那么是的。但这是一个更复杂的演示。实际上,我有一些结构指针指向结构深达几级的结构,任何级别的指针都可以被任意数量的线程改变,所以我需要指针本身是不稳定的。 – Exodist 2013-03-14 21:45:18