Создание базовой оболочки в C и проблемы с трубами / вилками

0

Сначала я хотел бы спросить, зачем нужны вилки в трубах? Я новичок в этом, но для меня я еще не понимаю, почему я не могу просто запустить один процесс слева от | затем выполните следующую часть после использования результата в качестве ввода. Я знаю, что вилки используются, но я не понимаю, почему и где они мне понадобятся.

Большое спасибо за ответ на этот вопрос, хотя это, наверное, глупый вопрос.

  • 0
    Суть в том, что в среде оболочки каждый pipe (например, echo "stuff" | sort создает отдельный процесс для каждой стороны канала | который работает под своим собственным PID . (Это эквивалентно fork в C). Interprocess связь осуществляется по pipes . Например, в C функции fork и popen . Никаких глубоких загадок - просто как это работает.
  • 0
    Вы могли бы реализовать конвейеры, как вы сказали, сохранив все выходные данные левой программы в файл, а затем запустив правую программу, считывающую файл как ввод. Это просто менее эффективно - две программы запускаются последовательно, а не параллельно, вам может понадобиться много места на диске и т. Д. Каналы занимают очень мало места на диске, порядка килобайт.
Показать ещё 1 комментарий
Теги:
pipe
fork

2 ответа

1
Лучший ответ

Прочитайте Advanced Linux Programming & intro (2); это -the ALP book- содержит несколько глав, объясняющих это. И, возможно, изучите исходный код некоторой свободной оболочки программного обеспечения. Используйте также strace (1)

Труба (7) имеет определенную (малую) емкость PIPE_BUF (несколько килобайт). Когда эта трубка заполнена, процесс записи блокируется. Когда процесс чтения считывает все, труба становится пустой, и процесс чтения блокируется. Таким образом, процесс записи получает возможность запускать и писать внутри него.

Поэтому вам нужно, чтобы оба процесса выполнялись одновременно (и они могли обменивать огромный объем данных - например, гигабайт за несколько секунд). А fork - единственный способ сделать новые процессы.

1

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню