我有一個結構,持有幾個指針。這些指針可以被幾個不同的線程改變。這些線程通過更改指針來更新結構,以便它指向另一個內存位置,它們永遠不會更改指向的值。根據我對易失性的理解,將結構中的這些指針聲明爲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