Подтвердить что ты не робот

Использование pipe для передачи целочисленных значений между родительским и дочерним

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

В моей программе я сначала создаю канал, затем я его развожу. Я предполагаю, что у меня есть "Два" трубы?

Из того, что я понимаю, это мое задание. Мой родитель проходит цикл for, проверяя целое значение "i" для определенной операции, увеличивает значение счетчика и сохраняет значение в массив. После каждой проверки мой родитель должен передать целочисленное значение "i" моему ребенку через канал. Затем мой ребенок использует это целочисленное значение, выполняет некоторую проверку значения и должен увеличить переменную count и сохранить результат в массиве [shared?]. В итоге; ребенок должен вернуть его окончательный счет родителям, который затем распечатывает два счета и "общий" массив.

- > Я не уверен, что мне нужно иметь общий массив или вообще сохранять результаты. Мне могут понадобиться только подсчеты - домашнее задание было неоднозначным, и я жду ответа от профессора. Также; могу ли я сделать общий массив между процессами? Это звучит как начало какой-то проблемы для меня.

- > Вот мои вопросы: Один; как использовать каналы для целых чисел? Я видел их только для массивов символов, и предыдущие ответы не кажутся возможными или законными..? Я не уверен. Не было разрешения, которое я мог бы найти на нем.

- > Как использовать однонаправленный канал для передачи целых чисел ребенку? И вернуть ребенка что-то? Я не уверен, как я могу... различать две трубы. Я "знаю" [или думаю, что знаю], что мне нужно закрыть одну неиспользованную часть каждого канала, чтобы избежать "некоторой неопределенной проблемы".

Извините за немые вопросы; Я еще не преподавал процессы (кроме вилки) или труб (вообще) в этом классе, поэтому я не уверен, с чего начать!

Вот части моего кода - это некрасиво, и это не работает, и я этого не ожидаю. Это больше заполнителя оболочки. Как только я выясню, как использовать трубку, я, вероятно, сделаю код понятным.

int main(void)
{
int fd[2];
pid_t childpid;
pid_t parentpid;
int i;
int threecount = 0;
int fivecount = 0;;
int results [MAXSIZE];

parentpid = getpid(); //Get current process ID number

pipe(fd);
childpid = fork(); 

if(childpid == 0){
close(fd[0]); //Closing this for some other reason

}
int j = 0;

if(childpid > 0)
close(fd[1]); //Closing this for some reason


if( childpid == -1 )
{
    perror("Failed to fork\n");
    return 1;
}
if (childpid > 0)
{
    for(i = 1; i < MAXSIZE;i++)
    {
        if(i % 5 == 0)
        {
            fivecount++;
            i = results[j];
            j++; 
            wait(NULL);
        }
    }
}
else if (childpid == 0)
    {
        if(i % 3 == 0) //This i here should probably be the i value above, piped to the child
        {
            threecount++;
            i = results[j];  //This should be part of th pipe
            j++;    //Trying to keep count of that shared array, not really the right way to do it though.
        }

    }
    printf("%d  %d  \n", fivecount,threecount);
    return 0;

}

4b9b3361

Ответ 1

Это примерно как lame (и отсутствие проверки ошибок, btw) образец, который я могу собрать для использования канала для отправки int от родителя к дочернему процессу, где ребенок был запущен из fork(). Он становится более сложным (очевидно) для отправки и получения данных, но я не могу сделать все для вас. Это просто вилки и ждет int (фактически, количество байтов, которые используются int) из дочернего элемента.

Обновление: Добавлен вариант отправки + ответа двухсторонней связи после этого. Для получения дополнительной информации см. Второй код.

Надеюсь, что это поможет.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    int fd[2];
    int val = 0;

    // create pipe descriptors
    pipe(fd);

    // fork() returns 0 for child process, child-pid for parent process.
    if (fork() != 0)
    {
        // parent: writing only, so close read-descriptor.
        close(fd[0]);

        // send the value on the write-descriptor.
        val = 100;
        write(fd[1], &val, sizeof(val));
        printf("Parent(%d) send value: %d\n", getpid(), val);

        // close the write descriptor
        close(fd[1]);
    }
    else
    {   // child: reading only, so close the write-descriptor
        close(fd[1]);

        // now read the data (will block)
        read(fd[0], &val, sizeof(val));
        printf("Child(%d) received value: %d\n", getpid(), val);

        // close the read-descriptor
        close(fd[0]);
    }
    return 0;
}

Вывод:

Parent(5943) send value: 100
Child(5945) received value: 100

Обновление: Расширены, чтобы включить отправку + ответа с использованием двух наборов труб

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

// some macros to make the code more understandable
//  regarding which pipe to use to a read/write operation
//
//  Parent: reads from P1_READ, writes on P1_WRITE
//  Child:  reads from P2_READ, writes on P2_WRITE
#define P1_READ     0
#define P2_WRITE    1
#define P2_READ     2
#define P1_WRITE    3

// the total number of pipe *pairs* we need
#define NUM_PIPES   2

int main(int argc, char *argv[])
{
    int fd[2*NUM_PIPES];
    int val = 0, len, i;
    pid_t pid;

    // create all the descriptor pairs we need
    for (i=0; i<NUM_PIPES; ++i)
    {
        if (pipe(fd+(i*2)) < 0)
        {
            perror("Failed to allocate pipes");
            exit(EXIT_FAILURE);
        }
    }

    // fork() returns 0 for child process, child-pid for parent process.
    if ((pid = fork()) < 0)
    {
        perror("Failed to fork process");
        return EXIT_FAILURE;
    }

    // if the pid is zero, this is the child process
    if (pid == 0)
    {
        // Child. Start by closing descriptors we
        //  don't need in this process
        close(fd[P1_READ]);
        close(fd[P1_WRITE]);

        // used for output
        pid = getpid();

        // wait for parent to send us a value
        len = read(fd[P2_READ], &val, sizeof(val));
        if (len < 0)
        {
            perror("Child: Failed to read data from pipe");
            exit(EXIT_FAILURE);
        }
        else if (len == 0)
        {
            // not an error, but certainly unexpected
            fprintf(stderr, "Child: Read EOF from pipe");
        }
        else
        {
            // report what we received
            printf("Child(%d): Received %d\n", pid, val);

            // now double it and send it back
            val *= 2;

            printf("Child(%d): Sending %d back\n", pid, val);
            if (write(fd[P2_WRITE], &val, sizeof(val)) < 0)
            {
                perror("Child: Failed to write response value");
                exit(EXIT_FAILURE);
            }
        }

        // finished. close remaining descriptors.
        close(fd[P2_READ]);
        close(fd[P2_WRITE]);

        return EXIT_SUCCESS;
    }

    // Parent. close unneeded descriptors
    close(fd[P2_READ]);
    close(fd[P2_WRITE]);

    // used for output
    pid = getpid();

    // send a value to the child
    val = 42;
    printf("Parent(%d): Sending %d to child\n", pid, val);
    if (write(fd[P1_WRITE], &val, sizeof(val)) != sizeof(val))
    {
        perror("Parent: Failed to send value to child ");
        exit(EXIT_FAILURE);
    }

    // now wait for a response
    len = read(fd[P1_READ], &val, sizeof(val));
    if (len < 0)
    {
        perror("Parent: failed to read value from pipe");
        exit(EXIT_FAILURE);
    }
    else if (len == 0)
    {
        // not an error, but certainly unexpected
        fprintf(stderr, "Parent(%d): Read EOF from pipe", pid);
    }
    else
    {
        // report what we received
        printf("Parent(%d): Received %d\n", pid, val);
    }

    // close down remaining descriptors
    close(fd[P1_READ]);
    close(fd[P1_WRITE]);

    // wait for child termination
    wait(NULL);

    return EXIT_SUCCESS;
}

(скомпилировать, например, gcc thisfile.c -o test)

Выход

Parent(2794): Sending 42 to child
Child(2797): Received 42
Child(2797): Sending 84 back
Parent(2794): Received 84