2016-03-27 11 views
0

これはかなり長い質問です。私がしようとしているのは、同時に2つのプロセスを実行することです。各プロセスは、ファイルfoo.txtを最後の番号を見つけてインクリメントしてファイルに戻します。明白な競争条件があるので、私はそれを避けるためにピーターソンのソリューションを実装しようとしています。プロセスはファイルに書き込みませんか?

これはすべてMinix3環境で行われます。私はすでにシステム上で実行されるすべてのプロセスに対して初期化される変数shared_valを定義しました。そして2つのシステムコール、get_svはshared_valの値を返し、set_svはshared_valにユーザ値を設定します。

私はPetersonのソリューションを実装するために各プロセスのshared_valの値を使用しています。また、2つのプロセスIDを.txtファイルconfig.txtに書き込んでいます。

コードは大丈夫ですが、foo.txtには書き込まれません。誰かがなぜそれが起こっているのかも説明できますか?

#include <stdio.h> 
#include <stdlib.h> 
#include "sys/types.h" 
#include <unistd.h> 
#include <strings.h> 
#define MAX 10000 

int main(int argc, char *argv[]) 
{ 
    int yourPID, status = 0, tempid, temp, temp1, i = 0, times; 
    int ch[10]; 
    int a, b, tempo, x, y; 
    FILE *fp, *fp1; 
    times = atoi((argv[1])); 
    ch[i++] = getpid(); 
    fp = fopen(argv[3], "a"); 
    while(i>=0) 
    { 
     fprintf(fp, "%d", ch[1]); 
     i--; 
    } 
    fclose(fp); 
    if(yourPID == ch[0]) 
    { 
     set_sv(0, &status); 
    } 
    if(yourPID == ch[1]) 
    { 
     set_sv(0, &status); 
    } 
    do 
    { 
     yourPID = getpid(); 
     if(yourPID == ch[0]) 
     { 
      temp = get_sv(ch[0], &status); 
     } 
     if(yourPID == ch[1]) 
     { 
      temp1 = get_sv(ch[1], &status); 
     } 
     sleep(1); 
     a = ~temp & ~temp1; 
     b = temp & temp1; 
     sleep(1); 
     if(yourPID == ch[0] && ((~a & ~b) == 0)) 
     { 
      char ch1[MAX], len, pos; 
      fp1 = fopen(argv[2], "r"); 
      while(!feof(fp)) 
      { 
       fscanf(fp1,"%s", ch1); 
      } 
      fclose(fp1); 
      len = strlen(ch1); 
      pos = len - 1; 
      tempo = ch1[pos] + 1; 
      fp1 = fopen(argv[2], "a"); 
      fprintf(fp1, "%c", tempo); 
      fclose(fp1); 
      tempo = get_sv(yourPID, &status); 
      if(tempo == 0) 
      { 
       tempo = 1; 
       set_sv(tempo, &status); 
      } 
      if(tempo == 1) 
      { 
       tempo = 0; 
       set_sv(tempo, &status); 
      } 
      sleep(1); 
      continue; 
     } 
     if(yourPID == ch[1] && ((~a & ~b) == 1)) 
     { 
      char ch1[MAX], len, pos; 
      fp1 = fopen(argv[2], "r"); 
      while(!feof(fp1)) 
      { 
       fscanf(fp1, "%s", ch1); 
      } 
      fclose(fp1); 
      len = strlen(ch1); 
      pos = len - 1; 
      tempo = ch[pos] + 1; 
      fp1 = fopen(argv[2], "a"); 
      fprintf(fp1, "%c", tempo); 
      fclose(fp1); 
      tempo = get_sv(yourPID, &status); 
      if(tempo == 1) 
      { 
       tempo = 0; 
       set_sv(tempo, &Status); 
      } 
      else 
      { 
       tempo = 1; 
       set_sv(tempo, &status); 
      } 
      sleep(1); 
      continue; 
     } 
    times = times - 1; 
    }while(times > 0); 
    return 0; 
} 

私は追いつくために他のプロセスの時間を与えるために、コード全体sleep(1)ステートメントを追加しました。私はこのために使用されてきた

bashのコマンドは、次のとおりです。5は、各プロセスがファイルへの書き込みをする回数である./safe_increment 5 foo.txt config.txt & ./safe_increment 5 foo.txt config.txt

答えて

1

これはコンパイルしないでください。あなたのPIDを宣言している最初の行は、状態のイニシャライザの後にエラーがあります。iという宣言は表示されません。これは、カットアンドペーストエラーかもしれませんが、あなたがやろうとしていることが明確でないか、単純にうまくいかないという事実が数多くあります。

一般に、sleep()を実行してもプロセス間の信頼性の高い同期は得られません。

+0

編集済みの誤植。 どのように動作させるためのヒント? –

+1

申し訳ありませんが、私はMinixを数十年間使用しておらず、Petersonのソリューションが何であるか分かりません。 mkdir()はいくつかのシステムではアトミックなので、ロックの代わりに使うことができます。 (あるプロセスがmkdir( "/ tmp/lock-dir")を実行し、ロックされた操作を実行した後、rmdir( "/ tmp/lock-dir" )、彼らは成功するまで共有リソースにアクセスできます。)HTH! –

関連する問題