Запуск канала fifo с одного терминала

#fork #exec

#разветвление #exec

Вопрос:

Мне было интересно, можно ли в любом случае запустить две программы, используя именованный канал, т.Е. fifo, выполнив только одну программу. Например, упомянутое здесь решение [Отправка строк между двумя каналами] [1] можно ли запустить его только с помощью одного терминала? Можно ли в любом случае вызвать writer.c из reader.c и запустить всю программу, просто запустив reader.c

РЕДАКТИРОВАТЬ: я удалил свой код, потому что у него было много проблем. Я использовал много функций, не имея о них никаких знаний.

ЗАКРЫТ.

Комментарии:

1. Одна программа или один процесс? Вы могли бы использовать одну программу, которая используется fork() для разделения на процесс записи и чтения.

2. В вашем названии указан один терминал? Вы знаете, что вы можете запускать несколько программ с одного терминала, не так ли? Запустите первую программу в фоновом режиме, затем запустите вторую.

3. как я могу запустить одну программу в фоновом режиме? Из приведенного выше примера, как я могу запустить writer.c, просто набрав ./reader.c в одном терминале

4. Используется amp; для запуска программы в фоновом режиме: writer amp;

5. В моем случае представьте, что пользователь не знает, что writer.c существует. Поэтому он просто запустит программу reader.c,

Ответ №1:

Используйте функцию popen() для запуска writer.py изнутри вашей программы чтения:

https://linux.die.net/man/3/popen

Функция popen возвращает ФАЙЛ *, который затем можно использовать с любой функцией ввода-вывода с буферизацией C. Например:

 #include <stdio.h>
#include <errno.h>

int main(int argc, char **argv) {

    FILE *fp;
    if((fp = popen("/path/to/writer.py", "r")) == NULL) {
        // handle error in some way
        perror("popen");
        exit(1);
    }

    size_t numbytes;
    char buffer[255];

    // Here we read the output from the writer.py and rewrite it to 
    // stdout.  The result should look the same as if you ran writer.py
    // by itself.. not very useful.  But you would replace this with code
    // that does something useful with the data from writer.py

    while((numbytes = fread(buffer, 1, sizeof(buffer), fp)) > 0) {
        fwrite(buffer, 1, numbytes, stdout);
        // should check for error here
    }

    pclose(fp);
    exit(0);
}
  

PS: Я не компилировал и не запускал эту программу, это просто пример, чтобы дать вам представление… Но это должно сработать. Также.. Я заметил, что вы говорите writer.c в одном месте и writer.py в другом. Не имеет значения, на каком языке написан writer. Пока путь к программе, который вы передаете popen(), приводит к записи выходных данных в стандартный вывод, он будет работать.

Комментарии:

1. Спасибо за ответ. Я отредактировал свой пост. Пожалуйста, дайте мне знать, как я могу использовать ваше решение popen в своем коде

2. Я не понимаю, где вы пытаетесь выполнить свою программу записи в опубликованном вами коде??? Вам не нужен fifo, просто обычный канал, который вам предоставит popen (popen() на самом деле вызывает системные вызовы (функции) pipe() и fork(), а также fdopen(), чтобы выполнить всю работу .. так что вам не нужно разбираться во всем этом самостоятельно. Используйте popen(), как я вам показал.)

3. Я должен использовать fifo. Есть ли возможность использовать канал fifo и запускать writer.py из Си?

4. Я вижу, ну .. popen проще, но поскольку вы делаете домашнее задание .. или мы делаем это .. посмотрите в учебнике. Конечно, профессор не заставлял вас использовать решение, которому не учили? Но да, если у вас есть одна программа, которая создает и считывает данные из fifo, а другая, которая открывает и записывает в этот fifo, вы можете просто использовать fork() , затем в дочернем процессе используйте exec() для запуска вашей программы записи. В Интернете есть множество примеров fork / exec, просто Google, и появятся тонны.

5. Хорошо, теперь посмотрим на ваш отредактированный вопрос. Вы должны понимать, что exec() не создает новый процесс .. он ЗАМЕНЯЕТ текущую запущенную программу новой в том же процессе. Итак, сначала вам нужно fork() . В результате получается две копии вашего устройства чтения. Теперь, если fork() возвращает 0, вы находитесь в дочернем элементе.. таким if(fork()==0) { exec(...); } образом, это приводит к запуску вашего writer, пока ваш reader продолжает. Теперь в коде для вашего writer вы должны открыть fifo q1 , который вы создали в программе чтения, но в режиме «w» .. и записать в него свои данные. Теперь вы можете читать из q1 в reader. Понял?