, Bu oldukça uzun bir soru, benimle birlikte kalın. Yapmaya çalıştığım şey aynı anda iki işlemi yürütmek. Her işlem bir dosyada foo.txt
son numarayı okur, artırır ve tekrar dosyaya ekler. Bariz yarış koşulları olacağından, bunu önlemek için Peterson'ın çözümünü uygulamaya çalışıyorum.İşlemler dosyaya yazılmıyor mu?
Bu, bir Minix3 ortamında gerçekleştirilir. Sistem üzerinde çalışan her işlem için başlatılan bir shared_val
değişkenini zaten tanımlamıştım. Ve iki syscalls, shared_val değerini döndüren get_sv
ve shared_val'a bir kullanıcı değeri ayarlayan set_sv
.
Peterson'ın çözümünü uygulamak için her işlemin shared_val değerlerini kullanıyorum. Ayrıca iki işlem kimliğini bir .txt dosyası config.txt
'a yazıyorum.
Kod tamamlandı, ancak foo.txt
yazmıyor. Birisi neden olabileceğini açıklayabilir mi?
#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;
}
ben yetişmek için diğer süreç zaman vermek, kod boyunca sleep(1)
ifadeleri ekledik.
Bunun için kullandım bash komutları
şunlardır: 5, her işlem dosyasına yazacak kaç kez./safe_increment 5 foo.txt config.txt & ./safe_increment 5 foo.txt config.txt
.
Düzenlenmiş yazım hataları. Nasıl yapılacağına dair ipuçları var mı? –
Üzgünüm, Minix'i birkaç yıldır kullanmadım ve Peterson'ın çözümünün ne olduğunu bilmiyorum. Mkdir() 'in bazı sistemlerde atomik olduğunu hatırlıyorum, böylece bir kilit yerine kullanabilirsiniz. (Bir işlem mkdir ("/ tmp/lock-dir"), kilitli işlemleri yapar ve daha sonra rmdir ("/ tmp/lock-dir"). Diğer işlemler mkdir ("/ tmp/lock-dir") üzerinde dönüş yapabilir) başarılı oluncaya kadar paylaşılan kaynağa erişebilirler.) HTH! –