#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 вы должны открыть fifoq1
, который вы создали в программе чтения, но в режиме «w» .. и записать в него свои данные. Теперь вы можете читать из q1 в reader. Понял?