Написать несколько случайных чисел в трубу? - PullRequest
1 голос
/ 14 декабря 2010

мой вопрос, могу ли я написать целое число в трубу? и как?

Мне нужно сделать 3 процесса: первый - 2 числа, второй - суммирование чисел, третий - вывод результата (ИСПОЛЬЗОВАНИЕ ТРУБЫ)

Спасибо всем

Ответы [ 2 ]

7 голосов
/ 14 декабря 2010

Сложная часть того, что вы пытаетесь сделать, - это создание конвейера. Вы можете просто сделать так, чтобы оболочка сделала это для вас ...

$ ./makenumbers | ./addnumbers | ./printresult

но это скучно, а? И вам нужно иметь три исполняемых файла. Итак, давайте посмотрим, что делают эти вертикальные полосы на уровне C.

Вы создаете канал с помощью системного вызова pipe. Вы переназначаете стандартный ввод / вывод с помощью dup2. Вы создаете новые процессы с fork, и вы ждете, пока они завершатся с waitpid. Программа для настройки всего этого будет выглядеть примерно так:

int
main(void)
{
    pid_t children[2];
    int pipe1[2], pipe2[2];
    int status;

    pipe(pipe1);
    pipe(pipe2);

    children[0] = fork();
    if (children[0] == 0)
    {
        /* in child 0 */
        dup2(pipe1[1], 1);
        generate_two_numbers_and_write_them_to_fd_1();
        _exit(0);
    }

    children[1] = fork();
    if (children[1] == 0)
    {
        /* in child 1 */
        dup2(pipe1[0], 0);
        dup2(pipe2[1], 1);
        read_two_numbers_from_fd_0_add_them_and_write_result_to_fd_1();
        _exit(0);
    }

    /* parent process still */
    dup2(pipe2[0], 0);
    read_a_number_from_fd_0_and_print_it();

    waitpid(children[0], &status, 0);
    waitpid(children[1], &status, 0);

    return 0;
}

Обратите внимание:

  • Я исключил всю обработку ошибок, потому что это сделало бы программу примерно втрое длиннее. Ваш инструктор хочет, чтобы вы включили обработку ошибок.
  • Точно так же я пропустил проверку статуса выхода детей; ваш инструктор также хочет, чтобы вы это проверили.
  • Вам не нужно dup2 звонков; Вы можете просто передать номера канала в вызовы подпрограмм. Но если бы у вас был exec - новый двоичный файл в дочернем файле, что более типично, они вам понадобятся. Тогда вам также придется позаботиться о том, чтобы все файловые дескрипторы с номерами от 3 и выше были закрыты.
  • Существует причина, по которой я использую _exit вместо exit. Попробуйте выяснить, что это такое.
  • Вам нужно использовать read и write вместо вызовов stdio.h в подпрограммах, вызываемых из дочерних процессов. Причина связана с тем, что я использую _exit.
3 голосов
/ 14 декабря 2010

Поскольку канал - это просто файл, вы можете использовать функцию fprintf () , чтобы преобразовать случайное число в текст и записать его в канал. Например:

FILE *pipe = popen("path/to/your/program", "w");
if (pipe != NULL) {
    fprintf(pipe, "%d\n", rand());
    pclose(pipe);
}
...