2016-12-22 16 views
0

Pthreadsを使用すると、スレッド1と2の間にグローバル共有変数fooがあるとします。mutexを使用せずにスレッド1からfooの値を読み取るのはスレッドセーフですか?スレッド1がfooを読み取る間、スレッド2がその値を変更していることは不可能ではないことに注意してください(ただし、あらかじめmutexをロックしているでしょう)。共有変数を読み書きはできませんが、スレッドセーフですか?

状況がこのようなものです:

#include <pthread.h> 
... 
int foo; 
pthread_mutex_t mutex; 
... 

void *thread1(void *t) { 
    while (foo<10) { 
    // do stuff 
    } 
    pthread_exit(NULL); 
} 

void *thread1(void *t) { 
    ... 
    pthread_mutex_lock(&mutex); 
    ... 
    foo++; 
    ... 
    pthread_mutex_unlock(&mutex); 
    ... 
    pthread_exit(NULL); 
} 

int main() { 
    ... 
} 
+0

私は読み取りと書き込みの両方をロックする必要があると思います。そうでないと、「汚れた読み」の可能性があります。 – duffymo

+1

あなたの例は2つの関数 'thread1()'を表示しているので明確ではありません。おそらく、あなたは 'thread1()'と 'thread2()'、あるいはそれに類するものを使うつもりです。書き込みは一般的に原子的であるという保証はないので、読み書きのためにmutexを使って 'foo'へのアクセスを保護する必要があります。 'foo'が構造型であれば、より深刻な問題になります。しかし、唯一安全な(sane)戦略は、共有変数を読み書きする前にmutexをロックすることです。 –

答えて

0

あなたは書き込みと読み込みを同期する必要がある値W/R場合は、その読み取り矛盾する可能性がありますので、あなたがしたい開始時にfoo = 0を読むように、それは、です書き込みは速くなるので、foo = 1と読んでください。

あなたの文脈では、その間に10回未満の反復があるため、はスレッドセーフではありませんです。

+0

これは私のアプリケーションの問題だとは分かりませんが... 'while'ループの反復回数は気にしません。' foo'が本当に '> = 10'のときに終了します。懸念は、読み込みのためにmutexをロックしていない方が、何かの空きメモリスロットのように、何かナンセンスを読んでいると脆弱になる可能性があるということです。 –

+0

mutexを使用しないとどういう意味で「読んでいないのか」を解説しました – Raskayu

+0

あなたがそれを説明した場所を見てください...もし書き込みが速くなり、foo = 1を読んだら、それは問題ではありません - 今はfoo = 1を意味します。何らかの理由でfoo = 2981232391(ある種の悪いメモリアクセス)を読んでしまうと問題が起こるでしょう。 –

3

さまざまな理由からスレッドセーフではありませんが、コンパイラはfooの読み取りをwhileループから引き上げた単一の読み取りに最適化することができます変化を見ることはありません。

+0

興味深い点..コンパイラは、ミューテックスによって保護されているものに適用できる最適化のレベルにどのような制限がありますか? – LWimsey

+1

私はさまざまな要因を知りませんが、主なものは、ミューテックスを取得する関数を呼び出すと、コンパイラが変数を知っている限り、変数をリロードする必要があることです関数によって変更された可能性があります。 –

関連する問題