Есть задача запустить процесс из приложения и перехватить его потоки ввода вывода для обмена информации с ним.
Прочитал много статей и советов, но не нашел красивого кросс-платформенного решения.
Здравствуйте, szag, Вы писали:
S>Есть задача запустить процесс из приложения и перехватить его потоки ввода вывода для обмена информации с ним. S>Прочитал много статей и советов, но не нашел красивого кросс-платформенного решения.
Ну так и перехватывать можно по-разному.
Я под Win32 как минимум 3 способа знаю, один не хуже другого.
Re: кросс-платформенный перехват stdin и stdout у child проц
Здравствуйте, szag, Вы писали:
S>Есть задача запустить процесс из приложения и перехватить его потоки ввода вывода для обмена информации с ним. S>Прочитал много статей и советов, но не нашел красивого кросс-платформенного решения.
Мы не можем кроссплатформенно подсунуть произвольному процессу оба пайпа (на вход и на выход).
В виндах можно — см. CreateProcess, STARTUPINFO.
А штатная позиксовая функция popen — позволяет перенаправить или вход, или выход. Понятное дело: она возвращает один дескриптор
Но мы можем подсунуть сколько угодно пайпов процессу, написанному нами же.
Просто в командной строке. См. в MSDN про функцию pipe(), там есть пример.
Далее, наш дочерний процесс читает (из командной строки) параметры
— номера пайпов
— командную строку, что надо запускать
Затем он подменяет свои стандартные потоки.
И запускает через exec() третий процесс.
Поскольку третий процесс наследует потоки, — ура, победа!
Перекуём баги на фичи!
Re[2]: кросс-платформенный перехват stdin и stdout у child п
К>Поскольку третий процесс наследует потоки, — ура, победа!
Спасибо! Однако, 3-й процесс похоже не потребуется, так как 2-ой, дочерний процесс тоже наш, а не произвольный. Я вот только что подумал, а не проще ли тогда заюзать boost::mpi, чем писать реализации для виндов и *nix'ов?
Или есть и тут подводные камни?
Re[3]: кросс-платформенный перехват stdin и stdout у child п
Здравствуйте, szag, Вы писали:
S>Спасибо! Однако, 3-й процесс похоже не потребуется, так как 2-ой, дочерний процесс тоже наш, а не произвольный. Я вот только что подумал, а не проще ли тогда заюзать boost::mpi, чем писать реализации для виндов и *nix'ов? S>Или есть и тут подводные камни?
Ой не знаю, не пробовал.
А вот с пайпами — всё легко и просто.
MSDN-овский пример, кстати говоря, с минимальной доработкой напильником прекрасно компилится и под цигвин. Так что, рекомендую!
Причём, можно в дочернем процессе — как напрямую к дескриптору пайпа обращаться (_write(fdpipe,....)),
так и взять и подменить dup2(fdpipe,STDIN_FILENO) — и после этого обращаться к scanf и т.п.
Наверно, выбор средств для межпроцессного взаимодействия определяется протоколом.
Если протокол изначально текстовый и синхронный — то достаточно пайпов.
Если какой-нибудь пакетный, да асинхронный, — тут надо курить в сторону сокетов, message queue, и т.п.
Вот здесь Boost.MPI пригодится
Перекуём баги на фичи!
Re[4]: кросс-платформенный перехват stdin и stdout у child п
Здравствуйте, Кодт, Вы писали:
S>>Спасибо! Однако, 3-й процесс похоже не потребуется, так как 2-ой, дочерний процесс тоже наш, а не произвольный. Я вот только что подумал, а не проще ли тогда заюзать boost::mpi, чем писать реализации для виндов и *nix'ов?
Пользуясь случаем тоже хочу спросить про mpi — он разве не требует надпрограмных механизмов(демонов или служб) для работы?
Re[5]: кросс-платформенный перехват stdin и stdout у child п
Здравствуйте, jerry_ru, Вы писали:
_>Пользуясь случаем тоже хочу спросить про mpi — он разве не требует надпрограмных механизмов(демонов или служб) для работы?
Судя по документации — требует.
Перекуём баги на фичи!
Re: кросс-платформенный перехват stdin и stdout у child проц
Здравствуйте, szag, Вы писали:
S>Здравствуйте!
S>Есть задача запустить процесс из приложения и перехватить его потоки ввода вывода для обмена информации с ним. S>Прочитал много статей и советов, но не нашел красивого кросс-платформенного решения.
Здравствуйте, szag, Вы писали:
S>Здравствуйте!
S>Есть задача запустить процесс из приложения и перехватить его потоки ввода вывода для обмена информации с ним. S>Прочитал много статей и советов, но не нашел красивого кросс-платформенного решения.
Дабы не создавать новую тему, немного дополню свой вопрос:
есть некое приложение, которое может запусть неопределенное количество копий второго приложения, необходимо придумать способ общения между ними,рассматривались:
1) буст интерпроцесс
2) сетевые сокеты
3) именованные каналы
у первого пункта минус — неизвестно сколько необходимо выделить памяти на общение изначально(в основном обмен идет небольший количеством данных, но бывают случаи, при которых объемы данных могут быть очень большими)
у второго: не хотелось бы создавать единый сервер и кучу клиентских сокетов
у третьего мультиплатформенность (в винде именованные каналы — это винапи функции
в линухах судя по коду кутэ — это каналы , смешанные опять же с сокетами)
Re: кросс-платформенный перехват stdin и stdout у child проц
S>Прочитал много статей и советов, но не нашел красивого кросс-платформенного решения.
Кросс-платформено это, вероятно, сделать нельзя — так же, как нельзя кросс-платформено форкануться. Это систем-специфик по определению.
Да здравствует мыло душистое и веревка пушистая.
Re[2]: кросс-платформенный обмен данными между процессами
Здравствуйте, szag, Вы писали:
S>>Есть задача запустить процесс из приложения и перехватить его потоки ввода вывода для обмена информации с ним. S>>Прочитал много статей и советов, но не нашел красивого кросс-платформенного решения.
S>Дабы не создавать новую тему, немного дополню свой вопрос: S>есть некое приложение, которое может запусть неопределенное количество копий второго приложения, необходимо придумать способ общения между ними,рассматривались: S>1) буст интерпроцесс S>2) сетевые сокеты S>3) именованные каналы
S>у первого пункта минус — неизвестно сколько необходимо выделить памяти на общение изначально(в основном обмен идет небольший количеством данных, но бывают случаи, при которых объемы данных могут быть очень большими) S>у второго: не хотелось бы создавать единый сервер и кучу клиентских сокетов S>у третьего мультиплатформенность (в винде именованные каналы — это винапи функции S>в линухах судя по коду кутэ — это каналы , смешанные опять же с сокетами)0
Честно говоря не очень понял проблему с первым вариантом. Создашь ты очередь на 100 сообщений по 64 кб, например. Если понадобится записать больше — порежь на куски, а на том конце собери их. На первый взгляд кажется что не сложно и в поток обернуть.
Главное гармония ...
Re[2]: кросс-платформенный обмен данными между процессами
Здравствуйте, szag, Вы писали:
S>1) буст интерпроцесс
он не предназначен для обмена частыми короткими сообщениями, внутри он весь просто истыкан вызовами функции: thread_yield(), что в свою очередь например под виндой вызывает { Sleep(1); }, тоесть спит он часто, много и не поделу(однако для передачи больших данных между процессами на одной машине вполне подходит).
S>2) сетевые сокеты
хороший вариант, ктомуже есть тотже boost::asio, что даёт вполне приятную обёртку над сокетами, хорошо интегрируется с boost::serialization.
S>3) именованные каналы
что-то по пайпам есть в boost::asio, но я их не смотрел.
ещё можете рассмотреть вариант использования boost::mpi.