IPC Qt/C#/C++, Межпроцессное взаимодействие |
Здравствуйте, гость ( Вход | Регистрация )
IPC Qt/C#/C++, Межпроцессное взаимодействие |
JustOneQuestion |
28.10.2015, 13:58
Сообщение
#1
|
Студент Группа: Новичок Сообщений: 13 Регистрация: 7.5.2015 Пользователь №: 4379 Спасибо сказали: 0 раз(а) Репутация: 0 |
Здравствуйте.
Ваш форум мне однажды уже помог с Qt, сейчас вот снова возникла потребность в помощи. Подозреваю тема не нова, но что-то сходу не нашёл ответа. Начну немного издалека, чтобы вопрос был более понятный. Просто боюсь что либо я не по канонам случайно использую слова, котоыре зарезервированы в языке, в ООП, и просто в сленге под совершенно конкретные понятия, и может вовсе не те которые я бы хотел. ) Предположим у нас на плате есть 2 микроконтроллера. Каждый их них имеет у себя вечный цикл в котором чёт делается. Время от времени, в цикле, микроконтроллеры могут впадать в спячку для снижения энергопотребления. В спячке он спит мертвым сном, ничего не опрашивая, ничего не делая, просто спит. Из спячки микроконтроллер может вывести дергание за ногу(кто-то из вне подаёт ноль или единичку на ногу). Микроконтроллер после этого просыпается и дальше чёт там делает. В нашем случае один из микроконтроллеров будет будить второго. Тоесть от второго к первому будет приходить СОБЫТИЕ для пробужения. Вот это я называю СПАТЬ ПОКА НЕ ПРИЙДЕТ КАКОЕТО "СОБЫТИЕ". (Слово событие EVENT как блин только не используют(что удивительно вполне себе законно), и иногда возникает путаница(по крайней мере у меня), я поэтому и привёл пример с микроконтроллерами). Дальше вопрос микроконтроллеров касаться уже не будет. Будет просто упоминание слова СОБЫТИЕ. Вот имено точно в таком же смысле как я сейчас описал. Суть вопроса: Пусть у нас на компе запущено два екзешника (2 разных процесса), более того они ещё и на разных языках написаны. При этом, они должны уметь друг другу слать СОБЫТИЯ (без данных! просто: либо есть событие либо его нет). Во время работы процессы, могут засыпать в ожидании события, чтобы пока делать нечего не грузить систему. Можно БЫЛО БЫ конечно заставить их по таймеру или в цилке опрашивать какуюто переменную в SharedMemory котору бы мог изменять второй проесс, но смысла нет грузить проц и ОС такой бредовой работой. Я написал пример как это реализовать для двух процессов на С++ и C#. Код ниже. Это две аналогичные по сути программы. Не мог ли бы вы, мне помочь с таким же ТРЕТЬИМ простым примером на Qt? С++ вариант:
C# вариант:
Спасибо за внимание. P.s.... Слышал вроде что как-то можно через QWinEventNotifier сделать, но может и иначе как-то можно... |
|
|
ViGOur |
28.10.2015, 15:37
Сообщение
#2
|
Мастер Группа: Модератор Сообщений: 3296 Регистрация: 9.10.2007 Из: Москва Пользователь №: 4 Спасибо сказали: 231 раз(а) Репутация: 40 |
Дело в том, что CreateEventEx платформо зависима, а Qt использует свои событийные механизмы, которые платформо независмые!.
Потому у тебя есть два варианта, либо лезть в потроха Qt и смотреть как реализована для винды событийная модель (в данном случае QWinEventNotifier), либо переходить на использование IPC общую для Windows/Linux. Посмотри Adding Windows event objects to a Qt event loop, там описано как сделать QWinEventNotifier на Qt. |
|
|
JustOneQuestion |
28.10.2015, 19:20
Сообщение
#3
|
Студент Группа: Новичок Сообщений: 13 Регистрация: 7.5.2015 Пользователь №: 4379 Спасибо сказали: 0 раз(а) Репутация: 0 |
Дело в том, что CreateEventEx платформо зависима, а Qt использует свои событийные механизмы, которые платформо независмые!. Потому у тебя есть два варианта, либо лезть в потроха Qt и смотреть как реализована для винды событийная модель (в данном случае QWinEventNotifier), либо переходить на использование IPC общую для Windows/Linux. Посмотри Adding Windows event objects to a Qt event loop, там описано как сделать QWinEventNotifier на Qt. Предполагал такой ответ. Начну с сылки. Я её видел... я qt очень плохо понимаю. В этом примере что-то много всего. Там зачем-то ещё один поток есть, но при этом нет именного события. Как тогда вобще получить како-нить идентификатор события если имени нет?... через что его в другой процесс передавать? Какими то обходными способами? Если вам понятно что в этом примере и как реализовано, пожалуйта, пожете написать пример-аналог того ктода что я на С++ написал? Там буквально десяток строк, если действительно понимать суть. Что касается зависимости/независимости от платформы, то собственно отчасти для этого момента я и привёл пример с микроконтроллерами. Программы должны уметь послылать друг другу события.. сигналы..(В ОБЩЕМ СУЛЧАЕ!!! я по-русски говорю! не надо путать с event signal и прочее). Я понимаю что реализация данного момента на разных ОС может быть разной, но она должна быть! и не важно как релизовано. Иначе это не ОС а не пойми что... Я могу любые микрокотроллеры между собой ногами соеденить, програмировать их хоть на чём, и всё равно - Они смогут друг другу события слать. В ОС просто обязана быть встроена возможно не просто тупо сидеть и в цикле или по таймеру проверять переменную или порт или ещё что-то, а реагировать на события от железа или других программ.. Прерывания жеж всегда были есть и будут на железном уровне. Если ОС не даёт с ними работать.. то это просто "ОС ЗЛА" Мне кроссплатформенность не нужна. Всё на винде будет. Поэтому я хотел бы, если можно, увидеть как можно реализовать передачу событий в другой процесс через аналог "именных событий", либо увидеть другой способ, который настоящий, кроссплотформенный, умеющий слать события в другое приложение. (И не просто прослушивать в цикле, а именно слать). |
|
|
ViGOur |
29.10.2015, 9:53
Сообщение
#4
|
Мастер Группа: Модератор Сообщений: 3296 Регистрация: 9.10.2007 Из: Москва Пользователь №: 4 Спасибо сказали: 231 раз(а) Репутация: 40 |
Работающий пример я к сожалению набросать не смогу, так как сижу по Linux, и винды рядом нет, как и дома.
Но на пальцах постараюсь объяснить. Разберем пример по ссылке, я его перенесу сюда с коментариями, в которых опишу что и как там происходит (и немного удалю ненужное, чтобы можно было спокойно откомпилить этот пример без плясок с бубном, тем более если не понимаешь что да как в Qt): "wineventtestthread.h"
"wineventtestthread.cpp"
"mainwindow.h"
"mainwindow.cpp"
По моему понятно, для чего нужен поток, чтобы основной поток не висел на WaitForSingleObject и занимался своими делами. |
|
|
JustOneQuestion |
29.10.2015, 22:52
Сообщение
#5
|
Студент Группа: Новичок Сообщений: 13 Регистрация: 7.5.2015 Пользователь №: 4379 Спасибо сказали: 0 раз(а) Репутация: 0 |
Большое спасибо, ViGOur за ваши коментарии к примеру. Помогло... хотя если честно я так и не понял что там и как работает Сейчас поясню.
Из ваших коментариев, стало понятно что в Qt можно подключить windows.h и ипользовать все стандартные Win API функции... Точнее НЕ ВСЕ!...но те что нужны CreateEvent, WaitForSingleObject, CloseHandle, SetEvent можно. НО! CreateEventEx например нету... почему..? Вроде всё работает хорошо. пример своего кода аналога на Qt я выложил ниже. Надо ещё потестить на скорость работы C++ варианта и Qt. Я для С# C++ сравнивал уже. Туда-сюда отправить событие + (мелкие затраты на дежуржые вещи в коде типа инкриментов счётчика цикла и проч) занимало 5мкс. Разброс от 3 до 8 примерно. максимум на 5, распределение не семитричное. Посмотрю как на Qt, будет ли разница... вроде не должна...(Мне просто интересно стало насколько быстро этот механизм работает...и насколько стабильно.. офф инфы не нашёл, решил проверить как смог сам). А вот с примером вашим я если честно так и не понял... где там мэин...вобще?! ))) В примере там что, по циклу шлём сами себе чтоли?...Вобщем мне неловко как-то что я смысл программы не могу понять даже после ваших коментариев... Но главный вопрос не в этом... зачем вабще нужен QWinEventNotifier?!?! Он вроде к делу не имеет ни какого отношения... так зачем оно вобще нам?! Вобщем, вот мой код(работает, проверил): Приложение создавал типа "консольное", дальше всё вроде по умолчанию. Для тестирования нужно запустить с примемр С++ что я выложил в первом посте.
p.s. прри создании консольного приложения засовывется строка QCoreApplication a(argc, argv); Я когда мышь навёл, увидел в подсказке что это якобы какойто бесконечный цикл... "сильно удивился"... скрестил пальцы в надежде что если я это сотру и попробую по старинке сам орагнизовать вечный цилк, то у меня хоть чтонить да зарабоатет... Даже побоялся читать про это... |
|
|
Litkevich Yuriy |
30.10.2015, 10:13
Сообщение
#6
|
разработчик РЭА Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: 94 |
Я когда мышь навёл, увидел в подсказке что это якобы какойто бесконечный цикл... нет, это не бесконечный цикл. Это инициализация всяких внутренних потрахов Qt, бесконечный цикл будет тут: цикл обработки сообщений. он закончится только когда будет вызван слот QCoreApplication::quit().чаще всего (но не всегда) для консольного приложения (QCoreApplication) не требуется цикл обработки событий (QCoreApplication::exec()), однако создавать объект QCoreApplication следует (подробности в его документации). Для GUI-приложения всегда требуется создавать и объект QGuiApplication (наследник QCoreApplication) и запускать цикл обработки событий (QGuiApplication::exec()) иначе приложение просто завершится не успев нарисовать себя на экране. Сообщение отредактировал Litkevich Yuriy - 30.10.2015, 13:35 |
|
|
ViGOur |
30.10.2015, 10:31
Сообщение
#7
|
Мастер Группа: Модератор Сообщений: 3296 Регистрация: 9.10.2007 Из: Москва Пользователь №: 4 Спасибо сказали: 231 раз(а) Репутация: 40 |
Тот пример, что ты набросал ничем не отличается от обычного виндового c WinApi, если хочешь Qt использовать, нужно делать так, как я описал выше, добавив свой main.cpp в котором запускается CMainWindow, такого хватит:
QWinEventNotifier нужен, как я писал выше, для `связывания ` Qt событий, с Windows событиями, чтобы при возникновении Windows события срабатывал Qt слот, в примере выше это MainWindow::eventSignaled. Что такое событийная модель Qt прочитай по ссылке: Сигналы и слоты. Описание на русском. К тому же WinApi часть примера тебе нужно переработать под себя, чтобы не посылались события самому себе. |
|
|
JustOneQuestion |
30.10.2015, 12:39
Сообщение
#8
|
Студент Группа: Новичок Сообщений: 13 Регистрация: 7.5.2015 Пользователь №: 4379 Спасибо сказали: 0 раз(а) Репутация: 0 |
Спасибо, про QWinEventNotifier вроде понял. Получается что к IPC оно не имет прямого отношения, а используется только для преобразования внешнего события во внутренние. Это альтернатива связки Второй поток+WaitForSingleObject, так? В конструкторе форм в C# помимо кнопок текстбоксов и прочего графического UI, на форму можно кидать SerialPort и Timer, которые будут так же генерировать события, как и все остальные контролы. QWinEventNotifier позволяет преобразовать внешнее событие, в событие которое может обрабатываться в форме... ну точнее в программе...через сигнал и слоты...Удобно вроде кажеться... по крайней мере можно придумать задачи где это действительно удобно и логично. Хотя, WaitForSingleObject нужен бывает для синхронизации потоков или процессов. И в таком случае нет смысла использовать QWinEventNotifier, а лучше как раз WaitForSingleObject .
Я ещё вот что хотел спросить. Есть ли в макОС и линуксе аналог "именных событий" для IPC? SharedMemory думаю везде обязано быть, а что с событиями? Ну и как продолжение вопроса, есть ли действительно кроссплатформенный подход для отправки событий между процессами? |
|
|
JustOneQuestion |
30.10.2015, 23:20
Сообщение
#9
|
Студент Группа: Новичок Сообщений: 13 Регистрация: 7.5.2015 Пользователь №: 4379 Спасибо сказали: 0 раз(а) Репутация: 0 |
Что-то грустно как-то с приерами от Qt, особенно консольных приложений... Тут есть вобще аналог msdn? не просто описание функций класса, а чтобы ещё и с примерами...
Подскажите пожалуйста: 1. Как получить хэндл консольного приложения, ... чтобы потом QWinEventNotifier использовать. 2. Можно ли слот вне класса завести?.. в ссылке что вы мне посоветовали, было написано что слот это "функция-член" всмысле член класса? а это обязательно? Может можно просто под мэйном ещё одну функцию описать, потом как-то дать понять всем и вся что это слот. После чего через коннект связать этот слоат с событием от QWinEventNotifier и радоваться простому и понятному примеру? Очень хочу протестить на скорость "Пример-аналог" но уже с использование слотов и QWinEventNotifier. |
|
|
Iron Bug |
31.10.2015, 13:54
Сообщение
#10
|
Профессионал Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: 12 |
Я ещё вот что хотел спросить. Есть ли в макОС и линуксе аналог "именных событий" для IPC? SharedMemory думаю везде обязано быть, а что с событиями? Ну и как продолжение вопроса, есть ли действительно кроссплатформенный подход для отправки событий между процессами? если хочешь именованные события, то в Linux аналогом будет fifo (named pipe) (пример использования fifo). есть ещё сокеты. насчёт макоси не знаю, но наверняка там это есть, ибо они юникс-совместимые. помимо Qt кроссплатформенные реализации IPC на С++ (для основных, наиболее распространённых систем) включают в себя такие библиотеки как boost (в частности, boost::interprocess), ACE (пример реализации IPC) |
|
|
Текстовая версия | Сейчас: 25.4.2024, 2:13 |