2016-03-25 17 views
0

スレッド間で共有メモリの変数にアクセスする必要がある状況があります。変数は、最初に定義され、継続的に更新されます。この既存のコードベースをバックグラウンドスレッドとして実行できるようにするコードを追加していますが、この共有変数からデータを読み取る必要があります。1つのスレッドだけがmutexを使用する場合、スレッド間の共有メモリが壊れますか?

私の質問は、更新されるたびに既存のコードベースにミューテックスを追加する必要がありますか?あるいは、データを読み込んでいる時に新しいコードにミューテックスを追加することはできますか?以下の小さなテストケースを作成しました。

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


typedef struct my_data { 

    int shared; 

}MY_DATA; 

MY_DATA data; 
pthread_mutex_t lock; 


void *background(void *x_void_ptr) 
{ 
    int i = 0; 
    int sleep_time; 
    while(i < 10) 
    { 

     data.shared++; 

     printf("BACK thread, Data = %d\n", data.shared); 

     sleep_time = rand()%5; 
     sleep(sleep_time); 
     i++; 
    } 


    return NULL; 

} 

int main() 
{ 


    int sleep_time; 
    pthread_t bg_thread; 


    if(pthread_create(&bg_thread, NULL, background, NULL)) { 

     fprintf(stderr, "Error creating thread\n"); 
     return 1; 

    } 

    MY_DATA *p_data = &data; 

    int i = 0; 
    while(i < 10) 
    { 
     pthread_mutex_lock(&lock); 
     printf("FOR thread, Data = %d\n", p_data->shared); 


     pthread_mutex_unlock(&lock); 
     sleep_time = rand()%5; 
     sleep(sleep_time); 

     i++; 
    } 



    // Finish up 
    if(pthread_join(bg_thread, NULL)) { 

     fprintf(stderr, "Error joining thread\n"); 
     return 2; 

    } 


    return 0; 

} 

出力:

FOR thread, Data = 0 
BACK thread, Data = 1 
BACK thread, Data = 2 
FOR thread, Data = 2 
FOR thread, Data = 2 
BACK thread, Data = 3 
BACK thread, Data = 4 
BACK thread, Data = 5 
FOR thread, Data = 5 
BACK thread, Data = 6 
BACK thread, Data = 7 
BACK thread, Data = 8 
FOR thread, Data = 8 
FOR thread, Data = 8 
BACK thread, Data = 9 
FOR thread, Data = 9 
BACK thread, Data = 10 
FOR thread, Data = 10 
FOR thread, Data = 10 
FOR thread, Data = 10 

はデータの破損(すなわち前景は、正しいデータを読んでいる)がないように見えますが、私の本能は私がする必要があると言っているこの回数を実行した後フォアグラウンドとバックグラウンドコードの両方にミューテックスを持つ。

+1

ミューテックスの概念を再読み込みしたいことがあります。 – alk

+1

ただ1つのスレッドからのミューテックスを使用することは意味がありません。だからあなたはそれを必要としないか、あなたはそれを間違ってしまった。多分、あなたはミューテックスが何のためにあるのかを見直すべきでしょう。 – Olaf

+1

プロセス内のすべてのグローバルメモリ(スレッドローカルストレージを除く)と関数内のローカル変数は、スレッド間で共有されることに注意してください。共有メモリは、プロセス間で共有されるメモリの用語です。スレッドまたはプロセスがメモリにアクセスしているかどうかにかかわらず、同じメモリに同時にアクセスする複数の実行スレッドがある場合は常に、アクセスが適切に管理されていることを確認する必要があります(たとえば、mutexなど)。 –

答えて

1

私のcommentから回答に材料を転送します。

プロセス内のすべてのグローバルメモリ(スレッドローカルストレージと関数内のローカル変数を除く)はすべてスレッド間で共有されることに注意してください。共有メモリは、プロセス間で共有されるメモリの用語です。

メモリがスレッドまたはプロセスによってアクセスされているかどうかにかかわらず、同じメモリに同時にアクセスできる複数の実行スレッドが存在する場合はいつでもアクセスを適切に管理する必要があります(たとえば、ミューテックスを使用)。最近では、マシン内で単一のコアが稼働していると仮定することはほとんどありません。そのため、潜在的な同時アクセスが一般的です。

-2

いいえ、あなたのメモリは壊れません。読み込みに影響はありません。 しかし、あなたは一貫性のない状態で読むでしょう、それは悪いことです。

+0

あなたの人は私が思ったことを確認している。前に述べたように、私は怠け者であり、このデータ構造に何度もアクセスするこの既存のコードベースを大幅に変更する必要はありませんでした。応答していただきありがとうございます。 – RG5

関連する問題