Название: QSharedMemory - сигнал на изменение своими руками Отправлено: JayFOX от Март 02, 2010, 20:17 Здравствуйте, необходимо как-то отловить изменения разделяемой памяти, пока не смог реализовать ничего кроме проверки по таймеру, но это плохо. Как я понял, есть расширенный вариант - QtSharedMemory, но это только за денежки(?).
Так можно ли как-нибудь с помощью QSharedMemory поймать её изменение? спасибо. Название: Re: QSharedMemory - сигнал на изменение своими руками Отправлено: Пантер от Март 02, 2010, 20:29 А если отнаследоваться и добавить такой фукнционал?
Название: Re: QSharedMemory - сигнал на изменение своими руками Отправлено: JayFOX от Март 02, 2010, 20:46 Вопрос в том - как узнать, была ли изменена память не по timer event, ну или чтобы приложение(процесс), которое изменяет эту память сообщило всем "клиентам" об изменении.
Название: Re: QSharedMemory - сигнал на изменение своими руками Отправлено: ритт от Март 02, 2010, 21:18 по таймеру. в своё время других вариантов не придумал...
Название: Re: QSharedMemory - сигнал на изменение своими руками Отправлено: alexman от Март 02, 2010, 21:28 пока не смог реализовать ничего кроме проверки по таймеру, но это плохо. Почему это по таймеру плохо? Название: Re: QSharedMemory - сигнал на изменение своими руками Отправлено: JayFOX от Март 02, 2010, 21:42 При таймфрейме секунда - мы имеем погрешность в секунду)
при минимальном(1 мс) - это грузит процессор, если же нет, то для меня это ситуация эквивалента Код: while(something.isSomeFlag()) Конечно, вышесказанное субъективно, но хочется как лучше. Видать решение будет найдено в win api. Спасибо за советы. Название: Re: QSharedMemory - сигнал на изменение своими руками Отправлено: Igors от Март 02, 2010, 23:47 Была такая необходимость, решил через 2 семафора (созданных в 2 процессах)
Название: Re: QSharedMemory - сигнал на изменение своими руками Отправлено: JayFOX от Март 03, 2010, 00:04 Можно, пожалуйста, подробнее.
Название: Re: QSharedMemory - сигнал на изменение своими руками Отправлено: SABROG от Март 03, 2010, 00:39 QSharedMemory сама использует семафоры. Я предлагаю такой вариант. Создать небольшой класс типа SharedEvent, где обязательными полями должны быть ID процесса (условно 0 и 1), ID события. Остальная часть памяти под данные. Помещаем эвент типа SharedEvent::Nothing в нашу разделяемую память. Создаем отдельный поток в каждом процессе и в бесконечном цикле вызываем QSharedMemory::lock(). Первый процесс, который захватил память считывает параметры события, проверяет равен ли ID процесса в эвенте его ID. Если равен, то это предыдущее его событие, которое так и не было обработано другим процессом. Отпускаем память и идем на второй заход. Если ID процесса не равно ему, то проверяем тип события, если это SharedEvent::Nothing, то опять отпускаем память и идем на второй круг. Тем временем другой процесс "подвиснет" в методе QSharedMemory::lock() дожидаясь когда ему вернут память. Когда это происходит, то выполняет с эвентом туже самую процедуру. Предположим, что наше событие имеет ID SharedEvent::ReadyRead и при этом ID процесса в этом событии также не равно тому ID, в котором оно проверяется. Тогда мы забираем данные и передаем их в главный поток. После передачи затираем старое событие новым эвентом, например SharedEvent::ReadyCompleted или просто пустым эвентом SharedEvent::Nothing. Но первый хорош тем, что позволяет на базе отчетов наблюдать за статусом передачи, прогрессбар передвинуть например.
Освобождаем память и второй процесс уже обрабатывает наш эвент или просто проверяет его в цикле. Как ни крути, а это всё тот же polling, возможно придется добавить таймер в поток, так как оба процесса будут постоянно читать расшаренную память и сравнивать события при простое (SharedEvent::Nothing). Хорошо то, что для GUI приложения это прозрачно. Название: Re: QSharedMemory - сигнал на изменение своими руками Отправлено: JayFOX от Март 03, 2010, 00:47 Спасибо, идея интересна, но дальше разблокировки gui мы не ушли. Раздумываю над системой семафоров...
Название: Re: QSharedMemory - сигнал на изменение своими руками Отправлено: Igors от Март 03, 2010, 01:17 Спасибо, идея интересна, но дальше разблокировки gui мы не ушли. Раздумываю над системой семафоров... Там получается совсем несложно даже без Qt. Семафоры удобно заводятся в разных процессах (как мне надо было) и могут быть общими. Один процесс записал что-то в shared memory и сделал sem_post (открыл семафор), другой стоял на sem_wait, семафор открылся, забрал из shared memory, отсигналил по второму семафору и опять ушел на sem_wait. Для второго процесса - то же самое. Ну правда в posix семафоры срабатывают по сигналам, это надо проверять. На Вындоуз - аналогично, только с мутексами. Название: Re: QSharedMemory - сигнал на изменение своими руками Отправлено: SABROG от Март 03, 2010, 01:37 Всё тоже самое, что ты сейчас написал происходит в QSharedMemory::lock(). А lock() у него на базе QSystemSemaphore (interprocess). Но как я понял человек хотел, чтобы event от ОС пришел "типа поменялось". А с семафорами выходит другая незадача. Один висит в lock'e дожидаясь пока ему освободят ресурс и вроде бы всё хорошо, а вот второму этот ресурс может быть нафиг не нужен, так как команды от пользователя не поступило и сидит ждет в каком-нибудь QEvenLoop сигнала из GUI например или из БД. При этом если связь между процессами нужна двухсторонняя, то уже хрен. А из этого вытекает, что клиент и сервер должны быть разными приложениями, вместо того, чтобы сделать их идентичными и полноправными.
Название: Re: QSharedMemory - сигнал на изменение своими руками Отправлено: Igors от Март 03, 2010, 03:01 Но как я понял человек хотел, чтобы event от ОС пришел "типа поменялось". Что человек хочет - это его дело. А моя задача была максимально быстрый обмен данными между 2 процессами (32 и 64 бит) - вот и пришлось крутить через shared memory.Название: Re: QSharedMemory - сигнал на изменение своими руками Отправлено: JayFOX от Март 04, 2010, 20:48 События изменения памяти можно получить через api, но это в ситуации и создания памяти через api (fileMapping), но QSharedMemory не даст доступ не qt-приложениям. Вопрос - тогда можно-ли сообщить другому процессу что-либо (например то, что мы изменили память), средствами qt?
Название: Re: QSharedMemory - сигнал на изменение своими руками Отправлено: SABROG от Март 04, 2010, 20:54 QLocalSocket (named pipe), создан как-раз для IPC.
Название: Re: QSharedMemory - сигнал на изменение своими руками Отправлено: JayFOX от Март 04, 2010, 22:25 Вопрос уже дурной, но: делам QLocalServer, к нему коннект QLocalSocket
Послать сообщение QLocalSocket::write(...) а поймать как? P.S.Не нашел в примере чата. Название: Re: QSharedMemory - сигнал на изменение своими руками Отправлено: SABROG от Март 04, 2010, 23:19 Как обычно, ловим сигнал: void QIODevice::readyRead ()
То есть сначала сервер принимает соединение: QLocalSocket * QLocalServer::nextPendingConnection () [virtual] а уж QLocalSocket на базе QIODevice. Название: Re: QSharedMemory - сигнал на изменение своими руками Отправлено: ритт от Март 06, 2010, 02:09 всё бы замечательно, но вы же не собираетесь использовать QLocalSocket для уведомления другой стороны о том, что блок шаренной памяти изменился, правда ведь? :Р
Название: Re: QSharedMemory - сигнал на изменение своими руками Отправлено: JayFOX от Март 06, 2010, 10:48 Да вот я тоже уже думаю, что получается прикольно)) интерес как-то стремится к абсурду)) Спасибо всем кто помог. Правильно-ли я понял - средствами QT не получить сигнал об изменении разделяемой памяти, кроме как lock() lock() и ждать unlock() а потом опять lock()?
P.S. Исключая QLocalSocket. Название: Re: QSharedMemory - сигнал на изменение своими руками Отправлено: Igors от Март 06, 2010, 13:16 Правильно-ли я понял - средствами QT не получить сигнал об изменении разделяемой памяти, кроме как lock() lock() и ждать unlock() а потом опять lock()? Я считаю что да, правильно. Вообще, что есть "сигнал об изменении разделяемой памяти"? (который Вы хотите получить). Допустим процесс 1 пишет что-то в shared memory. Вот сейчас 2 байта записаны, но запись-то продолжается. Вам ведь совсем не нужна реакция на каждое изменение shared memory. По любому процесс 1 должен закончить запись и выставить сигнал/флаг "готово" - а это просто семафор(ы). Ну и делайте их - через lock или по-другому, смысл все равно один.Название: Re: QSharedMemory - сигнал на изменение своими руками Отправлено: JayFOX от Март 06, 2010, 13:31 Да, все верно, спасибо.
Название: Re: QSharedMemory - сигнал на изменение своими руками Отправлено: JayFOX от Март 11, 2010, 19:25 Решил ситуацию с помощью winapi - CreateEvent() и WaitForSingleObject().
|