| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Программирование под Unix/Linux > неблокируемый ввод процесса |
| Автор: massiv 10.10.2009, 01:30 | ||
пытаюсь написать что то вроде автоматизации для инсталляхи. Потомок запускает инсталляху, родитель пишет в неё (отвечает на вопросы). Столкнулся с проблемой: как родитель узнает что потомок готов для того что бы в него писали? Пытаюсь использовать неблокируемый вывод, но что то не так......Вопрос в следующем: всё ли я делаю правильно? возможно есть способы проще? Код с коментами ниже (дял примера беру инсталляху открытого интеловского компилятора (в нём диалогом много
|
| Автор: massiv 10.10.2009, 10:57 | ||||
Разница в том , что родителю нужно осуществить последовательно несколько вводов, ввод нужно осуществлять только тогда когда потомок ждём ввода, на деле же получается так: запускаются два процесса, параллельно, например потомок ещё выводит диалоговое окно, а родитель успевает записать в его инпут 1-й , 2-й и 3-й символ, в то время как должен дождаться когда потомок выведет первый диалог и остановится в ожидании ввода - тогда родитель должен записать в него 1-й символ, дождаться когда когда потомок выведет второе диалоговое окно и только тогда родитель пишет в него 2-й символ, ну и наконец потомок выводит третье диалоговое окно и ждёт ввода - родитель пишет в него 3-й символ. Если записать вот так, без всяких блокировок:
то три вызова write в родителе выполнятся сразу же друг за другом и им всё равно что в этот момент происходит с потомком, готов ли он к вводу. Нужно как то "распараллелить" два процесса, вот в чём проблема |
| Автор: MAKCim 10.10.2009, 14:10 | ||
когда потомок захочет прочитать, он дернет read да и все pipe - это буферизированная структура, данные в нем храняться, пока с другого конца не будет осуществлено чтение |
| Автор: massiv 10.10.2009, 16:40 | ||||
нет, не получается, у меня начинает создаваться впечатление что дело в терминале, как то он себя не так ведёт, после 3-го write потомок должен ожидать ввода, НО в него почему то что то записывается, что - я не знаю, инсталляха уходит в бесконечный цикл (всё время пишет что некорректный ввод), приходится с другова терминала убивать её ( ^C не помогает). Почему такое происходит? Может быть пожно от потомка получать какой нибудь сигнал когда он останавливается в ожидании ввода и только потом писать в него??? |
| Автор: MAKCim 10.10.2009, 18:23 | ||||||
| massiv, не знаю, что у вас там с терминалом, но вот такая тестовая программа и скрипт работают как надо
вызов
|
| Автор: massiv 10.10.2009, 20:09 |
| Да действительно, проблем нет , попробовал ваш тестовый пример запустить со своей программной, всё корректно. Видимо инсталляха какая то особенная. Прочитал в теме выше от "Вывод строки из дочернего процесса" от Hromonin, там пишут что библиотека ncurses ведёт себя по особенному , не применятет напрямую stdin, stdout, похоже моя инсталляха написана именно на ней. |
| Автор: MAKCim 10.10.2009, 20:44 |
| massiv, протрассируйте через strace -f многое прояснится |
| Автор: massiv 11.10.2009, 14:13 |
| а есть ли ещё какой нибудь способ читать/писать запущенный exec процесс из основного помимо использования каналов? |
| Автор: MAKCim 11.10.2009, 14:44 |
| massiv, любой ipc |
| Автор: massiv 12.10.2009, 07:27 |
| ладно, спасибо Почитал про очереди сообщений, думаю что здесь их можно применить. Создание очереди , отправка/ получение сообщений, тут всё понятно , но как связать очередь с запученным execl процессом, ведь execl заменяет потомка запущенной программой, и я уже никак не могу контроллировать потомка, я знаю только его PID и всё... |
| Автор: svlary 13.10.2009, 06:07 | ||||
Для этого и придуман механизм генерации КЛЮЧЕЙ по имени ФАЙЛА. Т.е. Вы выделяете в разарабатываемой системе некий "самый главный" файл, без которооо она точно - работать не будет. А дальше генерируете КЛЮЧИ - столько, сколько Вам надо, и создаете (по ключам) очереди. Поскольку файл во всех Ваших программах используется ОДИН, то сгенерированные ключи будут одинаковы, а занчит, вы получите по ключам доступ к одим и тем же очередям :
Этот код (с флагом IPC_CREAT) должен быть в корневом процессе системы. В остальных процессах - без этого флага и только для того значения j, которое соответствует очереди этого процесса. Тут есть еще один тонкий момент... В то время. когда корневой процесс пытается СОЗДАТЬ очередь, она уже может СУЩЕСТВОВАТЬ, т.к. была создана ранеее. И даже более того - в этой очереди могут находиться сообщения. Что делать в такой ситуации - это уже Вам решать. |
| Автор: massiv 15.10.2009, 16:39 |
| Дело в том, что под "связать очередь с запученным execl процессом" я имел ввиду связать главный процесс (он выполняет функцию msgsend) с инпутом сторонней программы? То есть я хочу сделать с применением очередей тоже, что было реализовано выше с помощью каналов. |
| Автор: svlary 16.10.2009, 04:09 | ||
А в чем проблема ? Обе программы имеют один и тот же КЛЮЧ очереди. Обе программы открывают одну и ту же очередь с помощью msgget. Одна программа ложит сообщение в очередь с помощью msgsnd, другая - забирает это сообщение с помощью msgrcv. Все это практически одинаково с open, write и read. Добавлено через 2 минуты и 29 секунд - А вот это сделать в принципе невозможно. Очередь сообщений - это не файл и перенаправить ее на stdin невозможно. |
| Автор: massiv 16.10.2009, 13:04 | ||
на этот вопрос , MAKCim ответил , что можно использовать любой IPC |
| Автор: xvr 16.10.2009, 13:44 | ||||||
'Любой IPC' можно использовать для связи СВОИХ приложений.
|
| Автор: MAKCim 16.10.2009, 14:19 |
я бы добавил, что любой IPC, работа с которым осуществляется через отображаемый в юзерспейс файловый дескриптор ;) а это не только каналы |
| Автор: massiv 16.10.2009, 18:25 |
| Я вот подумал о модулях для работы с терминалом tty. В таких языках как perl, tcl/tk, питон такова рода автоматизация делается с помощью модулей работы с терминалом. Так может быть и в C можно осуществлять запись в независимый запущенный процесс с помощью функций работы с терминалом Linux (есть же terminfo, SLang)? |