これはかなり長い質問です。私がしようとしているのは、同時に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
。
編集済みの誤植。 どのように動作させるためのヒント? –
申し訳ありませんが、私はMinixを数十年間使用しておらず、Petersonのソリューションが何であるか分かりません。 mkdir()はいくつかのシステムではアトミックなので、ロックの代わりに使うことができます。 (あるプロセスがmkdir( "/ tmp/lock-dir")を実行し、ロックされた操作を実行した後、rmdir( "/ tmp/lock-dir" )、彼らは成功するまで共有リソースにアクセスできます。)HTH! –