кросс-платформенный перехват stdin и stdout у child процесса
От: szag  
Дата: 31.07.10 08:20
Оценка:
Здравствуйте!

Есть задача запустить процесс из приложения и перехватить его потоки ввода вывода для обмена информации с ним.
Прочитал много статей и советов, но не нашел красивого кросс-платформенного решения.
stdin stdout перехват потоков
Re: кросс-платформенный перехват stdin и stdout у child проц
От: okman Беларусь https://searchinform.ru/
Дата: 31.07.10 09:35
Оценка:
Здравствуйте, szag, Вы писали:

S>Есть задача запустить процесс из приложения и перехватить его потоки ввода вывода для обмена информации с ним.

S>Прочитал много статей и советов, но не нашел красивого кросс-платформенного решения.

Ну так и перехватывать можно по-разному.
Я под Win32 как минимум 3 способа знаю, один не хуже другого.
Re: кросс-платформенный перехват stdin и stdout у child проц
От: Кодт Россия  
Дата: 31.07.10 09:54
Оценка:
Здравствуйте, szag, Вы писали:

S>Есть задача запустить процесс из приложения и перехватить его потоки ввода вывода для обмена информации с ним.

S>Прочитал много статей и советов, но не нашел красивого кросс-платформенного решения.

Вот здесь — решение для linux (а, возможно, и для *nix вообще)
http://www.linuxquestions.org/questions/programming-9/where-do-i-get-a-bidirectional-popen-pipe-320699/
Проверил сейчас в виндах под цигвином — работает.
Чисто под винды не заработает, ибо там fork().

Однако...
Идея здесь такая.

Мы не можем кроссплатформенно подсунуть произвольному процессу оба пайпа (на вход и на выход).
В виндах можно — см. CreateProcess, STARTUPINFO.
А штатная позиксовая функция popen — позволяет перенаправить или вход, или выход. Понятное дело: она возвращает один дескриптор

Но мы можем подсунуть сколько угодно пайпов процессу, написанному нами же.
Просто в командной строке. См. в MSDN про функцию pipe(), там есть пример.

Далее, наш дочерний процесс читает (из командной строки) параметры
— номера пайпов
— командную строку, что надо запускать
Затем он подменяет свои стандартные потоки.
И запускает через exec() третий процесс.

Поскольку третий процесс наследует потоки, — ура, победа!
Перекуём баги на фичи!
Re[2]: кросс-платформенный перехват stdin и stdout у child п
От: szag  
Дата: 31.07.10 10:05
Оценка:
Здравствуйте, Кодт, Вы писали:


К>Поскольку третий процесс наследует потоки, — ура, победа!


Спасибо! Однако, 3-й процесс похоже не потребуется, так как 2-ой, дочерний процесс тоже наш, а не произвольный. Я вот только что подумал, а не проще ли тогда заюзать boost::mpi, чем писать реализации для виндов и *nix'ов?
Или есть и тут подводные камни?
Re[3]: кросс-платформенный перехват stdin и stdout у child п
От: Кодт Россия  
Дата: 31.07.10 10:25
Оценка:
Здравствуйте, 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 п
От: jerry_ru  
Дата: 31.07.10 14:27
Оценка:
Здравствуйте, Кодт, Вы писали:

S>>Спасибо! Однако, 3-й процесс похоже не потребуется, так как 2-ой, дочерний процесс тоже наш, а не произвольный. Я вот только что подумал, а не проще ли тогда заюзать boost::mpi, чем писать реализации для виндов и *nix'ов?


Пользуясь случаем тоже хочу спросить про mpi — он разве не требует надпрограмных механизмов(демонов или служб) для работы?
Re[5]: кросс-платформенный перехват stdin и stdout у child п
От: Кодт Россия  
Дата: 31.07.10 19:48
Оценка:
Здравствуйте, jerry_ru, Вы писали:

_>Пользуясь случаем тоже хочу спросить про mpi — он разве не требует надпрограмных механизмов(демонов или служб) для работы?


Судя по документации — требует.
Перекуём баги на фичи!
Re: кросс-платформенный перехват stdin и stdout у child проц
От: hotdox  
Дата: 01.08.10 16:35
Оценка:
Здравствуйте, szag, Вы писали:

S>Здравствуйте!


S>Есть задача запустить процесс из приложения и перехватить его потоки ввода вывода для обмена информации с ним.

S>Прочитал много статей и советов, но не нашел красивого кросс-платформенного решения.

http://doc.qt.nokia.com/4.6/qprocess.html
Qt может, он кроссплатформенный
Re: кросс-платформенный обмен данными между процессами
От: szag  
Дата: 02.08.10 11:58
Оценка:
Здравствуйте, szag, Вы писали:

S>Здравствуйте!


S>Есть задача запустить процесс из приложения и перехватить его потоки ввода вывода для обмена информации с ним.

S>Прочитал много статей и советов, но не нашел красивого кросс-платформенного решения.

Дабы не создавать новую тему, немного дополню свой вопрос:
есть некое приложение, которое может запусть неопределенное количество копий второго приложения, необходимо придумать способ общения между ними,рассматривались:
1) буст интерпроцесс
2) сетевые сокеты
3) именованные каналы

у первого пункта минус — неизвестно сколько необходимо выделить памяти на общение изначально(в основном обмен идет небольший количеством данных, но бывают случаи, при которых объемы данных могут быть очень большими)
у второго: не хотелось бы создавать единый сервер и кучу клиентских сокетов
у третьего мультиплатформенность (в винде именованные каналы — это винапи функции
в линухах судя по коду кутэ — это каналы , смешанные опять же с сокетами)
Re: кросс-платформенный перехват stdin и stdout у child проц
От: Vamp Россия  
Дата: 02.08.10 14:23
Оценка:
S>Прочитал много статей и советов, но не нашел красивого кросс-платформенного решения.
Кросс-платформено это, вероятно, сделать нельзя — так же, как нельзя кросс-платформено форкануться. Это систем-специфик по определению.
Да здравствует мыло душистое и веревка пушистая.
Re[2]: кросс-платформенный обмен данными между процессами
От: Mazay Россия  
Дата: 03.08.10 11:42
Оценка:
Здравствуйте, szag, Вы писали:

S>>Есть задача запустить процесс из приложения и перехватить его потоки ввода вывода для обмена информации с ним.

S>>Прочитал много статей и советов, но не нашел красивого кросс-платформенного решения.

S>Дабы не создавать новую тему, немного дополню свой вопрос:

S>есть некое приложение, которое может запусть неопределенное количество копий второго приложения, необходимо придумать способ общения между ними,рассматривались:
S>1) буст интерпроцесс
S>2) сетевые сокеты
S>3) именованные каналы

S>у первого пункта минус — неизвестно сколько необходимо выделить памяти на общение изначально(в основном обмен идет небольший количеством данных, но бывают случаи, при которых объемы данных могут быть очень большими)

S>у второго: не хотелось бы создавать единый сервер и кучу клиентских сокетов
S>у третьего мультиплатформенность (в винде именованные каналы — это винапи функции
S>в линухах судя по коду кутэ — это каналы , смешанные опять же с сокетами)0

Честно говоря не очень понял проблему с первым вариантом. Создашь ты очередь на 100 сообщений по 64 кб, например. Если понадобится записать больше — порежь на куски, а на том конце собери их. На первый взгляд кажется что не сложно и в поток обернуть.
Главное гармония ...
Re[2]: кросс-платформенный обмен данными между процессами
От: Sni4ok  
Дата: 03.08.10 13:55
Оценка:
Здравствуйте, szag, Вы писали:

S>1) буст интерпроцесс


он не предназначен для обмена частыми короткими сообщениями, внутри он весь просто истыкан вызовами функции: thread_yield(), что в свою очередь например под виндой вызывает { Sleep(1); }, тоесть спит он часто, много и не поделу(однако для передачи больших данных между процессами на одной машине вполне подходит).

S>2) сетевые сокеты


хороший вариант, ктомуже есть тотже boost::asio, что даёт вполне приятную обёртку над сокетами, хорошо интегрируется с boost::serialization.

S>3) именованные каналы


что-то по пайпам есть в boost::asio, но я их не смотрел.
ещё можете рассмотреть вариант использования boost::mpi.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.