5 / 5 / 0
Регистрация: 10.10.2014
Сообщений: 86
|
||||||
1 | ||||||
Не получается сделать конвейер на пайпах15.08.2018, 01:00. Показов 1574. Ответов 5
Здравствуйте.
Изучаю основы программирования под Linux, сейчас вот пробую разобраться с межпроцессорным взаимодействием, а именно - с пайпами. Есть такой код:
Что делает: с одной командой работает, но с несколькими создает пустой файл result, данные между вызовами теряются. Прикрутил вывод, чтобы смотреть как соединяю вводы - выводы пайпами - вроде все как нужно, либо я в принципе неверно понимаю суть работы с пайпами. Объясните, пожалуйста, что я делаю не так
0
|
15.08.2018, 01:00 | |
Ответы с готовыми решениями:
5
Конвейер Конвейер Скрипт-Конвейер Поточный конвейер |
Параллельный Кот
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
|
|
15.08.2018, 02:39 | 2 |
Вы уверены, что правильно понимаете, как работает системный вызов fork() ?
Если кратко, то fork() создает точную копию родительского процесса, после чего уже два одинаковых (ничем не отличимых) процесса продолжают свою работу со следующей команды после ветвления. Один из способов их отличить - fork() вернет родителю id потомка, а потомок вместо этого получит 0. Здесь пока в вашей программе все правильно. Далее, что делают ваши процессы? (1) Родительский процесс, убедившись, что он не потомок, переходит к следующей команде, снова "форкает" себя и т.д. для каждой команды из списка. (2) Все потомки (!) являются потомками одного и того же родительского процесса! Каждый из них делает какие-то там манипуляции с каналами и потоками ввода/вывода, после чего заменяет свой образ на указанный в команде, не переходя к следующей команде. Итого: хотели сделать цепочку вызовов, а получили звезду. Кажется, немного не то. Необходимо каким-то образом заставить потомков не сразу выполнять exec(), а сначала перейти к следующей команде, "форкнуть" себя, а только потом обработать свою команду. А первоначального родителя отучить от вредной привычки плодить свои копии. Надеюсь, натолкнул на мысли, как исправить ошибки. Если не совсем понятно или что-то не получится - пишите, попробую сделать пример программы, некоторый опыт в этой области имеется.
0
|
5 / 5 / 0
Регистрация: 10.10.2014
Сообщений: 86
|
|
15.08.2018, 09:21 [ТС] | 3 |
Да, с этим разобрался. И copy on write при назначении пайпов как раз учел.
А вот тут я проблем и не видел (приложил картинку). Полагал, если в ядре мы подменили дескриптор на пайповский, то даже не страшно если exec выполнится раньше чем будет готов читать следующий процесс - данные буфферизируются и процесс прочитает их когда будет готов. Видимо, я неправильно это понимаю, попробую сейчас переписать это рекурсивно, причем начинать плодить видимо нужно с последней команды, чтобы после exec она ожидала ввода stdin от создаваемой на следующем шаге команды.
0
|
5 / 5 / 0
Регистрация: 10.10.2014
Сообщений: 86
|
||||||
15.08.2018, 10:09 [ТС] | 4 | |||||
И рекурсивно тоже не работает. Не понимаю, что я делаю не так
0
|
15.08.2018, 10:28 | 5 |
В твои коды не смотрел.
Можешь попробовать взять за основу https://www.cyberforum.ru/c-li... post973482
0
|
5 / 5 / 0
Регистрация: 10.10.2014
Сообщений: 86
|
||||||
15.08.2018, 13:14 [ТС] | 6 | |||||
Изучил логи strace - неправильно я дескрипторы закрывал!
Работающее рекурсивное решение (может, кому пригодится):
0
|
15.08.2018, 13:14 | |
15.08.2018, 13:14 | |
Помогаю со студенческими работами здесь
6
про конвейер Весовой конвейер Стандартный конвейер Комплектовочный конвейер Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |