Russian Qt Forum
Ноябрь 23, 2024, 04:01 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Простое взаимодействие 2-х приложений  (Прочитано 7992 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Ноябрь 15, 2011, 09:32 »

Добрый день

Есть 2 приложения, назовем их Agent и Worker. можем перестраивать оба как хотим.

Agent занят приемом и передачей пакетов по сети.  Когда получен пакет "job", Agent должен:

- проверить статус Worker'а, если тот занят, то ответить по сети "занято". Иначе
- записать файл исходных данных "input.dat",
- запустить приложение Worker. Если Worker уже запущен и ждет, то сообщить ему что появился новый inpiut.dat.
- ждать когда Worker закончит работу и создаст файл "output.dat",
- отправить output.dat по сети

Worker ни о какой сети ничего не знает. Он умеет принимать input.dat, производить массу расчетов и формировать output.dat. Если произошла ошибка (или Worker вылетел по exception), то  input.dat не удаляется. Message ошибки остается висеть пока пользоаатель его не закроет. Если input.dat нет, то Worker ждет 5 минут, потом молча выходит.

Необходимо обеспечить взаимодействие Agent-Worker, так чтобы Agent мог с определенным интервалом времени сообщать по сети текущий статус:

- "работает" (Worker работает)
- "готово" (Worker закончил)
- "ошибка" (Worker выставил error или отвалился)
- "аборт" (Worker был закрыт пользователем)

Также необходимо быть 100% уверенным что отправляемый output.dat полностью записан и соответствует input.dat

Как бы Вы делали (или без "бы" т.к. задача довольно типовая)

Спасибо
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #1 : Ноябрь 15, 2011, 10:27 »

d-bus. к сожалению, его кажется нет под винду и мак.
Записан
BRE
Гость
« Ответ #2 : Ноябрь 15, 2011, 10:33 »

d-bus. к сожалению, его кажется нет под винду и мак.
Под вендой можно собрать dbus (в сети видел "историю успеха").

2Igors Пайпы же, и ГУЙ не нужен.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Ноябрь 16, 2011, 10:53 »

2Igors Пайпы же, и ГУЙ не нужен.
Оба приложения имеют UI (хотя и небольшие). Это  "сетевой вариант" уже имеющейся, работающей задачи. Никогда не использовал pipe/fork и имею о них весьма смутные понятия (что-то вроде переназначить stdout). Если речь идет об обмене данными между приложениями, то это не проблема, через shared memory - милое дело, но нужна еще и синхронизация.

d-bus. к сожалению, его кажется нет под винду и мак.
Понятно что люди этим не раз занимались, и накатанные решения должны быть. Но изыскивать довольно большую либу для 2 платформ и потом от нее зависеть - ну для этого нужны основания, в данном случае их маловато. Никаких серверов/клиентов в обозримом будущем не предвидится, есть одна частная задача.   
Записан
ivm2008
Новичок

Offline Offline

Сообщений: 9


Просмотр профиля
« Ответ #4 : Ноябрь 16, 2011, 11:08 »

а что мешает использовать 127.0.0.1 и какой-нито подходящий свободный порт? Ничем не хуже dbus...
Записан
SASA
Гость
« Ответ #5 : Ноябрь 16, 2011, 12:37 »

Какая платформа?
Записан
BRE
Гость
« Ответ #6 : Ноябрь 16, 2011, 13:10 »

Если речь идет об обмене данными между приложениями, то это не проблема, через shared memory - милое дело, но нужна еще и синхронизация.
Вот это и удивляет. Есть превосходный механизм для обмена данными между процессами, который просто организовать и использовать, он есть на всех платформах... но "милое дело" почему-то SharedMem, сокеты, именованные пайпы, файлы или их комбинации, требующие делать синхронизации и кучу всего другого. Улыбающийся

Никогда не использовал pipe/fork и имею о них весьма смутные понятия (что-то вроде переназначить stdout).
Да, это что то типа stdout.
Agent запускает worker'а. Воркер пишет в трубу свое текущее состояние (готов, начал обработку, завершил обработку, завершаюсь), которое читает Агент, а Агент (по своей трубе) может писать команды для Воркера. Если Воркер завершается по какой-то причине, Агент получает уведомление об этом, и может "понять" упал Воркер или завершился штатно, ну и перезапустить его если нужно.
В самом простом случае можно использовать popen, а для более серьезного обмена подойдет QProcess или boost.process (эта библиотека пока не входит в boost, но лежит у них в песочнице) + boost.asio.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #7 : Ноябрь 16, 2011, 13:58 »

Если платформа X11, то, имхо, проще и легче XSelection нет.
Записан

Qt 5.11/4.8.7 (X11/Win)
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #8 : Ноябрь 16, 2011, 16:24 »

может RPC ? чуть попозже может ссылку на либу кину, попадалась хорошая, правда на бусте.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Ноябрь 16, 2011, 21:25 »

Платформы: Mac и Вындоуз. Использовать Qt возможности нет, буст можно.

Agent запускает worker'а. Воркер пишет в трубу свое текущее состояние (готов, начал обработку, завершил обработку, завершаюсь), которое читает Агент, а Агент (по своей трубе) может писать команды для Воркера. Если Воркер завершается по какой-то причине,
А что такое "читает"? Я так понимаю (поправьте если нужно): допустим (с помощью каких-то средств) я даже могу задействовать удобную ф-цию read - читать как с консоли. И что с того? Задача не может стоять ждать ввода, значит надо этот read делать в отдельной нитке. А если так то что чем же плох (несолиден) тот же SharedMem - ну с определенным интервалом проверяю изменилось ли содержимое ячейки. Скорость здесь не критична, Worker обрабатывает данные за секунды, часто - минуты и больше. Или то же самое через сокет - кому что нравится.

Но в любом случае (какой бы способ обмена данными ни выбран) - неясно чего писать, и что должно делать каждое приложение получив данные. По существу - сценарий синхронизации
Записан
BRE
Гость
« Ответ #10 : Ноябрь 16, 2011, 21:44 »

Задача не может стоять ждать ввода, значит надо этот read делать в отдельной нитке.
Зачем? Я не зря написал про asio, а именно он позволит читать асинхронно, именно тогда, когда придут данные с другого конца пайпа.
Можно использовать массу разных механизмов, но почему бы не использовать тот, который совмещается с запуском дочернего процесса (а здесь все равно желателен если  не обязателен контроль жив ли воркер или уже упал). А этот механизм обмена как раз организуется при запуске child-процесса.

Но в любом случае (какой бы способ обмена данными ни выбран) - неясно чего писать, и что должно делать каждое приложение получив данные. По существу - сценарий синхронизации
Ты же вроде все расписал в первом посте.
Агент должен уметь запустить воркер, контролировать что его процесс жив и читать его состояние (возможно посылать ему команды). А воркер должен уметь сообщать свое состояние (и если надо читать команды агента).
Или в чем вопрос?
Записан
ecspertiza
Супер
******
Offline Offline

Сообщений: 1053


С уважением, мастер конфетного цеха!


Просмотр профиля
« Ответ #11 : Ноябрь 17, 2011, 08:28 »

Вот, нашел, http://www.codeproject.com/KB/threads/RMI_For_Cpp.aspx

в кратце два приложения используют один файл описания функций\классов и т.д. И можно из одного приложения вызывать методы другого, вроде удобно Улыбающийся да и работает довольно шустро
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Ноябрь 19, 2011, 12:40 »

А я в курсе Улыбающийся И даже пару лет назад задавал вопросы автору, с его слов понял что на нижнем уровне используются сокеты. Но опять-таки встает вопрос "привлечения либы" (пост #3)

Зачем? Я не зря написал про asio, а именно он позволит читать асинхронно, именно тогда, когда придут данные с другого конца пайпа.
Оба приложения используют нативные циклы/обработчики событий Mac/Win. Неясно удастся ли пришедшие данные оформить в виде "событий" - во всяком случае для этого нужно прилагать усилия, и, вероятно, задействовать еще тулзы.

Но получив желанную "асинхронку" я хз что с ней делать Улыбающийся  Ну например, вроде простой случай: пользователь прервал Worker (abort). Мои действия? Выясняется что "просто так" перезапустить Worker нельзя - он сначала должен завершиться. Ну и дальше все в том же духе. Покрутившись с этим неск дней я вижу что это поразительно напоминает "state machine" (если я правильно понимаю этот термин). Есть множество "состояний", одни те же события могут быть ошибками в одном состоянии/контексте и нормальными в другом. Как читать/обмениваться данными - дело десятое.

В общем сделал на shared, спасибо за обсуждение и наводки.
Записан
SASA
Гость
« Ответ #13 : Ноябрь 20, 2011, 11:13 »

Я делал под винду.
Есть такое сообщение WM_COPYDATA.
Позволяет пересылать данные между процессами. У 1-ой программы завел окошко с именем "очень_длинный_гуид_приёмщик_первой_программы". Во второй программе нахожу это окошко (FindWindow) и посылаю ему сообщение.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.054 секунд. Запросов: 23.