詳細:
競合状態を回避するために、ピーターソンのアルゴリズム(以下)を実装しています。私がやりたい方法は、グローバル整数変数を宣言し、スレッド 1 と 2 を作成することです。スレッド 1 がグローバル変数にアクセスできるときはいつでも、出力a
してグローバル変数カウンターに 1 を追加する必要があります。スレッド 2 がこのグローバル変数にアクセスできる場合、出力b
してグローバル変数カウンターに 1 を追加する必要があります。これは、グローバル変数が特定の数 (10 としましょう) に達するまで継続する必要があります。その後、スレッド(グローバル変数に最後に追加した2つのスレッドのいずれか)がグローバル変数を1にリセットし、両方のスレッドが終了する必要があります。これまでに実装したコードは、競合状態を回避しますが、カウンターが制限に達したときに両方のスレッドを終了できません。
質問:
カウンターが特定の制限に達したときに、どうすれば両方のスレッドを終了できますか。
スレッドを終了する適切な形式は何ですか。現在、exit() を使用していますが、これはあまり効率的ではないと思います。
ピーターソンのアルゴリズム
boolean flag [2];
int turn;
void P0()
{
while (true) {
flag [0] = true;
turn = 1;
while (flag [1] && turn == 1) /* do nothing */;
/* critical section */;
flag [0] = false;
/* remainder */;
}
}
void P1()
{
while (true) {
flag [1] = true;
turn = 0;
while (flag [0] && turn == 0) /* do nothing */;
/* critical section */;
flag [1] = false;
/* remainder */
}
}
void main()
{
flag [0] = false;
flag [1] = false;
parbegin (P0, P1);
}
私のコード:
編集:カウンター制限値をチェックしているifステートメントをクリティカルセクションに配置する必要があることに気付きました(フラグをfalseに変更する前に)。
#include<stdlib.h>
#include<stdio.h>
#include<pthread.h>
int counter = 0;
int flag[2];
int turn;
void *func1(void *);
void *func2(void *);
int main(int argc,char *argv[]){
pthread_t thread1,thread2;
//int rt1,rt2;
flag[0] = 0;
flag[1] = 0;
//rt1 = pthread_create(&thread1,NULL,&func1,"a");
//rt2 = pthread_create(&thread2,NULL,&func2,"c");
pthread_create(&thread1,NULL,&func1,"a");
pthread_create(&thread2,NULL,&func2,"b");
pthread_join(thread1,NULL);
pthread_join(thread2,NULL);
return 0;
}// End of main function
void *func1(void *message){
while(1){
flag[0] = 1;
turn = 1;
while(flag[1] && turn == 1);
printf("%s %d\n",(char *)message,counter);
counter++;
flag[0] = 0;
if(counter == 10){
counter = 1;
printf("exited at func1, with counter %d\n",counter);
exit(0);
}
}
return 0;
}
void *func2(void *message){
while(1){
flag[1] = 1;
turn = 0;
while(flag[0] && turn == 0);
printf("%s %d\n",(char *)message,counter);
counter++;
flag[1] = 0;
if(counter == 10){
counter = 1;
printf("exited at func2, with counter %d\n",counter);
exit(0);
}
}
return 0;
}