1

私は、期待される値と実際に読み取られた値を出力するときに、境界のあるバッファーからの書き込みと読み取りを単に示すプログラムを作成しています。N を低い値として定義すると、プログラムは期待どおりに実行されます。ただし、値を大きくすると、予期しない結果が表示され始めます。私が理解していることから、2 つのスレッドを使用してデータ競合を作成しています。

出力を見ると、次のように、データ競合の約 3 つの例に絞り込んだと思います。

  1. 1 つのスレッドがバッファーに書き込み、別のスレッドが読み取ります。
  2. 2 つのスレッドが同時にバッファーに書き込みます。
  3. 2 つのスレッドが同時にバッファーから読み取ります。

以下は私のコードです。#include ステートメントの書式設定は非常に奇妙なので、省略しました。

#define BUFFSIZE 10000
#define N   10000

int Buffer[BUFFSIZE];

int numOccupied = 0;    //# items currently in the buffer
int firstOccupied = 0;  //where first/next value or item is to be found or placed

//Adds a given value to the next position in the buffer
void buffadd(int value)
{

Buffer[firstOccupied + numOccupied++] = value;
}


 int buffrem()
{

numOccupied--;
return(Buffer[firstOccupied++]);

}

void *tcode1(void *empty)
{
int i;

//write N values into the buffer

for(i=0; i<N; i++)
    buffadd(i);
}

void *tcode2(void *empty)
{
int i, val;

//Read N values from the buffer, checking the value read with what is expected for testing

for(i=0; i<N; i++)
{
    val = buffrem();
    if(val != i)
        printf("tcode2: removed %d, expected %d\n", val, i);

}
}


main()
{
pthread_t tcb1, tcb2;

pthread_create(&tcb1, NULL, tcode1, NULL);
pthread_create(&tcb2, NULL, tcode2, NULL);

pthread_join(tcb1, NULL);
pthread_join(tcb2, NULL);
}

ここに私の質問があります。

  1. これらのデータ競合は (私のコードの) どこで発生しますか?
  2. どうすれば修正できますか?
4

2 に答える 2

1

numOccupied両方のスレッドが同じグローバル変数とにアクセスするため、競合が発生しfirstOccupiedます。変数へのアクセスを何らかの形式のロックと同期する必要があります。たとえば、セマフォまたはミューテックスを使用して、追加/削除操作中に共有グローバル状態へのアクセスをロックできます。

于 2012-04-13T23:43:04.773 に答える
1

ミューテックスを使用して、共有データ構造へのアクセスを同期します。次のものが必要です。

pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);
pthread_mutex_lock(&mutex);
pthread_mutex_unlock(&mutex);
pthread_mutex_destroy(&mutex);

基本的な原則として、スレッド間で共有されるデータ構造を読み書きする前にミューテックスをロックし、後でロックを解除します。この場合、BufferプラスのメタデータnumOccupiedfirstOccupiedは、保護する必要がある共有データ構造です。したがって、buffadd()buffrem()では、最初にミューテックスをロックし、最後にロックを解除します。また、main()では、スレッドを開始する前にミューテックスを初期化し、参加後に破棄します。

于 2012-04-13T23:45:48.083 に答える