スレッド間で共有メモリの変数にアクセスする必要がある状況があります。変数は、最初に定義され、継続的に更新されます。この既存のコードベースをバックグラウンドスレッドとして実行できるようにするコードを追加していますが、この共有変数からデータを読み取る必要があります。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
はデータの破損(すなわち前景は、正しいデータを読んでいる)がないように見えますが、私の本能は私がする必要があると言っているこの回数を実行した後フォアグラウンドとバックグラウンドコードの両方にミューテックスを持つ。
ミューテックスの概念を再読み込みしたいことがあります。 – alk
ただ1つのスレッドからのミューテックスを使用することは意味がありません。だからあなたはそれを必要としないか、あなたはそれを間違ってしまった。多分、あなたはミューテックスが何のためにあるのかを見直すべきでしょう。 – Olaf
プロセス内のすべてのグローバルメモリ(スレッドローカルストレージを除く)と関数内のローカル変数は、スレッド間で共有されることに注意してください。共有メモリは、プロセス間で共有されるメモリの用語です。スレッドまたはプロセスがメモリにアクセスしているかどうかにかかわらず、同じメモリに同時にアクセスする複数の実行スレッドがある場合は常に、アクセスが適切に管理されていることを確認する必要があります(たとえば、mutexなど)。 –