Несколько процессов с конвейером, неожиданное изменение переменной? - PullRequest
0 голосов
/ 20 апреля 2020

Я знаю, это звучит нереально "неожиданное изменение переменной". Поскольку я не мог определить проблему, я использовал это название ...

Во-первых, это моя домашняя работа. Домашнее задание заключается в чтении двух матриц из файла, а затем создании 4 дочерних процессов, родитель отправит (через канал) четверть фрагментов матрицы дочерним процессам. Дочерний процесс выполнит свои вычисления, после чего они отправят вычисленные индексы обратно в родительский процесс (через канал снова. Попытка получить двунаправленные каналы здесь.), Чтобы родительский элемент напечатал вычисленные значения в stdout и вернул.

В настоящее время я прочитал эти матрицы из файла, создал 3 процесса (шел шаг за шагом), отправил 1/4 матрицы каждому из трех процессов и попытался проверить, удалось мне это или нет.

Проблема "в общем", что происходит, если я вижу third_start переменная (в той же области видимости), поэтому она даже не вводит l oop.

Также я наблюдал еще пару вещей;

  1. При перенаправлении вывода в какой-то файл данные выглядят как% 10 моей программы, написанной там.
  2. Если я предоставить матрицу с меньшими значениями, как матрицы 4x4. Проблема с third_start не возникает.

Я уверен, что я делаю что-то глупое.

Вот часть моего кода. (Немного грязно, я не так отправляю свои домашние задания. Пожалуйста, игнорируйте расчеты о матрицах.)

int pipe_fds[2]; //first pipe
int pipe_fds2[2];//second pipe
int pipe_fds3[2];//third pipe
int pipe_fds4[2];//fourth pipe
int pip_ret, pip_ret2, pip_ret3, pip_ret4;

int pid2,pid3,pid4,pid5; //assumed p1 is parent and 2,3,4,5 are child processes.
int single_x; //store single_x val;
int single_y;
pip_ret = pipe(pipe_fds);
pid2 = fork();
if(pip_ret == -1)
{
    fprintf(stderr, "%s\n", "Unable to create pipe\n");
    exit(1);
}

else if(pid2 == 0)
{
    if (close(pipe_fds[1]) == -1)
    {
        perror("close");
        exit(EXIT_FAILURE);
    }


    int first_quarter_x[_pow(2, n) / 2][_pow(2, n) / 2];
    int first_quarter_y[_pow(2, n) / 2][_pow(2, n) / 2];
    for(i = 0 ; i <  _pow(2, n) / 2 ; ++i)
    {
        for(j = 0 ; j < _pow(2, n) / 2; ++j)
        {
            if(read(pipe_fds[0], &single_x, sizeof(single_x)) <= 0)
            {
                perror("read failed ");
                exit(EXIT_FAILURE);
            }
            first_quarter_x[i][j] = single_x;


            if(read(pipe_fds[0], &single_y, sizeof(single_y)) <= 0)
            {
                perror("read failed ");
                exit(EXIT_FAILURE);
            }
            first_quarter_y[i][j] = single_y;
            fprintf(stderr,"(2)Child with pid %d received value %d\n",getpid(), single_x);
            fprintf(stderr,"(2)Child with pid %d received value %d\n",getpid(), single_y);
        }

    }




    for(i = 0 ; i <  _pow(2, n) / 2 ; ++i)
    {
        for(j = 0 ; j < _pow(2, n) / 2; ++j)
        {
            if(matrixA[i][j] == first_quarter_x[i][j])
            {
                fprintf(stderr,"Good2a\n" );
            }
            else
            {
                fprintf(stderr,"Bad2a.\n" );
            }
        }
        fprintf(stderr,"\n" );
    }

    for(i = 0 ; i <  _pow(2, n) / 2 ; ++i)
    {
        for(j = 0 ; j < _pow(2, n) / 2; ++j)
        {
            if(matrixB[i][j] == first_quarter_y[i][j])
            {
                printf("Good2b\n" );
            }
            else
            {
                printf("Bad2b.\n" );
            }
        }
        fprintf(stderr,"\n" );
    }
    exit(EXIT_SUCCESS);

}


pip_ret2 = pipe(pipe_fds2);
pid3 = fork();




if(pip_ret2 == -1)
{
    fprintf(stderr, "%s\n", "Unable to create pipe for 3.process\n");
    exit(1);
}

else if(pid3 == 0)
{

    if (close(pipe_fds2[1]) == -1)
    {
        perror("close");
        exit(EXIT_FAILURE);
    }
    int second_start = _pow(2, n) / 2;
    int second_quarter_x[_pow(2, n) / 2][_pow(2, n) / 2];
    int second_quarter_y[_pow(2, n) / 2][_pow(2, n) / 2];
    for(i = 0 ; i <  _pow(2, n) / 2 ; ++i)
    {
        for(j = second_start ; j < _pow(2, n); ++j)
        {
            if(read(pipe_fds2[0], &single_x, sizeof(single_x)) <= 0)
            {
                perror("read failed ");
                exit(EXIT_FAILURE);
            }
            second_quarter_x[i][j] = single_x;

            if(read(pipe_fds2[0], &single_y, sizeof(single_y)) <= 0)
            {
                perror("read failed ");
                exit(EXIT_FAILURE);
            }
            second_quarter_y[i][j] = single_y;

            fprintf(stderr,"(3)Child with pid %d received value %d\n",getpid(), single_x);
            fprintf(stderr,"(3)Child with pid %d received value %d\n",getpid(), single_y);
        }
    }




    for(i = 0 ; i <  _pow(2, n) / 2 ; ++i)
    {
        for(j = second_start ; j < _pow(2, n) ; ++j)
        {
            if(second_quarter_x[i][j] == matrixA[i][j])
            {
                fprintf(stderr,"Good3a \n" );
            }
            else
            {
                fprintf(stderr,"Bad3a\n" );
            }
        }
        fprintf(stderr,"\n" );
    }

    for(i = 0 ; i <  _pow(2, n) / 2 ; ++i)
    {
        for(j = second_start ; j < _pow(2, n) ; ++j)
        {
            if(second_quarter_y[i][j] == matrixB[i][j])
            {
                fprintf(stderr,"Good3b \n" );
            }
            else
            {
                fprintf(stderr,"Bad3b\n" );
            }
        }
        fprintf(stderr,"\n" );
    }

    exit(EXIT_SUCCESS);
}



pip_ret3 = pipe(pipe_fds3);
pid4 = fork();




if(pip_ret3 == -1)
{
    fprintf(stderr, "%s\n", "Unable to create pipe for 4.process\n");
    exit(1);
}

else if(pid4 == 0)
{
    if (close(pipe_fds3[1]) == -1)
    {
        perror("close");
        exit(EXIT_FAILURE);
    }
    int third_start = _pow(2, n) / 2;
    printf("THIRD START IS %d\n",third_start ); //here it prints normal.
    int third_quarter_x[_pow(2, n) / 2][_pow(2, n) / 2];
    int third_quarter_y[_pow(2, n) / 2][_pow(2, n) / 2];
    for(i = third_start ; i <  _pow(2, n) ; ++i)
    {
        for(j = 0 ; j < _pow(2, n) / 2; ++j)
        {
            if(read(pipe_fds3[0], &single_x, sizeof(single_x)) <= 0)
            {
                perror("read failed ");
                exit(EXIT_FAILURE);
            }
            third_quarter_x[i][j] = single_x;

            if(read(pipe_fds3[0], &single_y, sizeof(single_y)) <= 0)
            {
                perror("read failed ");
                exit(EXIT_FAILURE);
            }
            third_quarter_y[i][j] = single_y;

            fprintf(stderr,"(4)Child with pid %d received value %d\n",getpid(), single_x);
            fprintf(stderr,"(4)Child with pid %d received value %d\n",getpid(), single_y);
        }
    }
    printf("THIRD START IS %d\n",third_start ); //then it prints something anormal...

    for(i = third_start ; i <  _pow(2, n) ; ++i)
    {
        for(j = 0 ; j < _pow(2, n) / 2; ++j)
        {
            if(third_quarter_x[i][j] == matrixA[i][j])
            {
                fprintf(stderr,"Good4a \n" );
            }
            else
            {
                fprintf(stderr,"Bad4a\n" );
            }
        }
        printf("\n" );
    }

    for(i = third_start ; i <  _pow(2, n) ; ++i)
    {
        for(j = 0 ; j < _pow(2, n) / 2; ++j)
        {
            if(third_quarter_x[i][j] == matrixB[i][j])
            {
                fprintf(stderr,"Good4b \n" );
            }
            else
            {
                fprintf(stderr,"Bad4b\n" );
            }
        }
        fprintf(stderr,"\n" );
    }

    exit(EXIT_SUCCESS);
}





        //parent start
    if (close(pipe_fds[0]) == -1)
    {
        perror("close");
        exit(EXIT_FAILURE);
    }
    fprintf(stderr,"First quarter beginning \n");
    for(i = 0 ; i <  _pow(2, n) / 2 ; ++i)
    {
        for(j = 0 ; j < _pow(2, n) / 2; ++j)
        {
            single_x = matrixA[i][j];
            single_y = matrixB[i][j];
            write(pipe_fds[1], &single_x, sizeof(single_x));
            write(pipe_fds[1], &single_y, sizeof(single_y));
            fprintf(stderr,"Parent with pid %d sent value to 2 %d\n",getpid(), single_x);
            fprintf(stderr,"Parent with pid %d sent value to 2 %d\n",getpid(), single_y);
        }

    }
    wait(NULL);
    fprintf(stderr,"First quarter end\n \n");




    fprintf(stderr,"Second quarter beginning\n");

    if (close(pipe_fds2[0]) == -1)
    {
        perror("close");
        exit(EXIT_FAILURE);
    }
    int sec = _pow(2,n) / 2;

    for(i = 0 ; i <  _pow(2, n) / 2 ; ++i)
    {
        for(j = sec ; j < _pow(2, n); ++j)
        {
            single_x = matrixA[i][j];
            single_y = matrixB[i][j];
            write(pipe_fds2[1], &single_x, sizeof(single_x));
            write(pipe_fds2[1], &single_y, sizeof(single_y));
            fprintf(stderr,"Parent with pid %d sent value to 3 %d\n",getpid(), single_x);
            fprintf(stderr,"Parent with pid %d sent value to 3 %d\n",getpid(), single_y);
        }

    }
    wait(NULL);
    fprintf(stderr,"Second quarter end\n");



    fprintf(stderr,"Third quarter beginning\n");

    if (close(pipe_fds3[0]) == -1)
    {
        perror("close");
        exit(EXIT_FAILURE);
    }
    int third = _pow(2,n) / 2;

    for(i = third ; i <  _pow(2, n) ; ++i)
    {
        for(j = 0 ; j < _pow(2, n) / 2; ++j)
        {
            single_x = matrixA[i][j];
            single_y = matrixB[i][j];
            write(pipe_fds3[1], &single_x, sizeof(single_x));
            write(pipe_fds3[1], &single_y, sizeof(single_y));
            fprintf(stderr,"Parent with pid %d sent value to 4 %d\n",getpid(), single_x);
            fprintf(stderr,"Parent with pid %d sent value to 4 %d\n",getpid(), single_y);
        }

    }
    wait(NULL);
    fprintf(stderr,"Third quarter end\n");

Ответы [ 2 ]

2 голосов
/ 21 апреля 2020

int pipe_fds2[2];//second pipe

Косвенная помощь: нумерованные переменные почти всегда лучше представлены в виде массивов. Возможно, вам нужен массив структур

struct child_t {
    int datapipe[2], resultpipe[2];
    pid_t pid;
    int result;
} children[4];

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

Организовав ваши данные таким образом, вы избавляетесь от соблазна дублировать код, потому что al oop в массиве проще. Меньшее количество кода означает меньше ошибок, поэтому вы быстрее выполняете домашнюю работу.

1 голос
/ 20 апреля 2020

Вы получаете доступ вне массивов.

    int third_start = _pow(2, n) / 2;
    printf("THIRD START IS %d\n",third_start ); //here it prints normal.
    int third_quarter_x[_pow(2, n) / 2][_pow(2, n) / 2];
    int third_quarter_y[_pow(2, n) / 2][_pow(2, n) / 2];

Индексы обоих измерений third_quarter_x и third_quarter_y go от 0 до third_start-1. Но тогда у вас есть следующие циклы:

    for(i = third_start ; i <  _pow(2, n) ; ++i)
    {
        for(j = 0 ; j < _pow(2, n) / 2; ++j)
        {

Значения i находятся вне диапазона индексов для первого измерения. Поскольку вы пишете вне массива, вы вызываете неопределенное поведение.

Циклы должны оба go с 0 до third_start.

У вас есть похожая проблема в предыдущий процесс с second_start, за исключением того, что он делает это в j l oop.

...