1

詳細:

競合状態を回避するために、ピーターソンのアルゴリズム(以下)を実装しています。私がやりたい方法は、グローバル整数変数を宣言し、スレッド 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;
}
4

1 に答える 1

0

明らかに、1 つのスレッドがグローバル カウンターをリセットすると、もう 1 つのスレッドはグローバル カウンターが eg10 に到達するのを決して見ることができないため、終了することはありません。グローバル カウンターをリセットせず、グローバル カウンター (例: 10) が見つかるたびにスレッドを終了させたらどうなるでしょうか。本当にカウンターをリセットしたい場合は、親 (メイン) スレッド (グローバル カウンターを定義する場所でもあります) で行います。

スレッドの終了に関しては、単純にプライマリ スレッド関数から戻る (これによりスレッドが自動的に終了します)、スレッド内から呼び出す、またはメイン関数からpthread_exit使用することができます。phtread_cancel

于 2014-11-14T13:08:10.210 に答える