Процессы не пишут в файл?

, Это довольно длинный вопрос, так что потерпите меня. Я пытаюсь запустить два процесса одновременно. Каждый процесс будет читать файл foo.txt, находить последнее число, увеличивать его и добавлять обратно в файл. Поскольку будут очевидные условия гонки, я пытаюсь реализовать решение Петерсона, чтобы избежать этого.

Все это делается в среде Minix3. Я уже определил переменную shared_val, которая инициализируется для каждого процесса, работающего в системе. И два системных вызова, get_sv, который возвращает значение shared_val, и set_sv, который устанавливает пользовательское значение в shared_val.

Я использую значения shared_val каждого процесса для реализации решения Петерсона. Я также записываю два идентификатора процесса в файл .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, которые я использовал для этого: ./safe_increment 5 foo.txt config.txt & ./safe_increment 5 foo.txt config.txt

Где 5 — количество раз, которое каждый процесс будет записывать в файл.


person Kshitij Bantupalli    schedule 27.03.2016    source источник


Ответы (1)


Это даже не должно компилироваться — первая строка, объявляющая yourPID, содержит ошибку после инициализатора для состояния, и я не вижу объявления i. Это может быть ошибка вырезания и вставки, но есть много последующих вещей, которые неясно, что вы пытаетесь сделать, или это просто не сработает.

В общем, просто sleep() не даст вам надежной межпроцессной синхронизации.

person Dave M.    schedule 27.03.2016
comment
Извините, я не использовал Minix несколько десятков лет и не знаю, какое решение предлагает Петерсон. Я помню, что в некоторых системах mkdir() является атомарным, поэтому вы можете использовать его вместо блокировки. (Один процесс выполняет mkdir(/tmp/lock-dir), выполняет заблокированные операции, а затем rmdir(/tmp/lock-dir). Другие процессы могут использовать mkdir(/tmp/lock-dir), пока не добьются успеха, и тогда они смогут получить доступ к общему ресурсу.) HTH! - person Dave M.; 28.03.2016