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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QSharedMemory - сигнал на изменение своими руками  (Прочитано 15669 раз)
JayFOX
Гость
« : Март 02, 2010, 20:17 »

Здравствуйте, необходимо как-то отловить изменения разделяемой памяти, пока не смог реализовать ничего кроме проверки по таймеру, но это плохо. Как я понял, есть расширенный вариант - QtSharedMemory, но это только за денежки(?).
Так можно ли как-нибудь с помощью QSharedMemory поймать её изменение?
спасибо.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #1 : Март 02, 2010, 20:29 »

А если отнаследоваться и добавить такой фукнционал?
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
JayFOX
Гость
« Ответ #2 : Март 02, 2010, 20:46 »

Вопрос в том - как узнать, была ли изменена память не по timer event, ну или чтобы приложение(процесс), которое изменяет эту память сообщило всем "клиентам" об изменении.
Записан
ритт
Гость
« Ответ #3 : Март 02, 2010, 21:18 »

по таймеру. в своё время других вариантов не придумал...
Записан
alexman
Гость
« Ответ #4 : Март 02, 2010, 21:28 »

пока не смог реализовать ничего кроме проверки по таймеру, но это плохо.

Почему это по таймеру плохо?
Записан
JayFOX
Гость
« Ответ #5 : Март 02, 2010, 21:42 »

При таймфрейме секунда - мы имеем погрешность в секунду)
при минимальном(1 мс) - это грузит процессор, если же нет, то для меня это ситуация эквивалента
Код:
while(something.isSomeFlag())

Конечно, вышесказанное субъективно, но хочется как лучше.
Видать решение будет найдено в win api. Спасибо за советы.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Март 02, 2010, 23:47 »

Была такая необходимость, решил через 2 семафора (созданных в 2 процессах)
Записан
JayFOX
Гость
« Ответ #7 : Март 03, 2010, 00:04 »

Можно, пожалуйста, подробнее.
Записан
SABROG
Гость
« Ответ #8 : Март 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 приложения это прозрачно.
« Последнее редактирование: Март 03, 2010, 00:41 от SABROG » Записан
JayFOX
Гость
« Ответ #9 : Март 03, 2010, 00:47 »

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

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Март 03, 2010, 01:17 »

Спасибо, идея интересна, но дальше разблокировки gui мы не ушли. Раздумываю над системой семафоров...
Там получается совсем несложно даже без Qt. Семафоры удобно заводятся в разных процессах (как мне надо было) и могут быть общими. Один процесс записал что-то в shared memory и сделал sem_post (открыл семафор), другой стоял на sem_wait, семафор открылся, забрал из shared memory, отсигналил по второму семафору и опять ушел на sem_wait. Для второго процесса - то же самое. Ну правда в posix семафоры срабатывают по сигналам, это надо проверять. На Вындоуз - аналогично, только с мутексами.
Записан
SABROG
Гость
« Ответ #11 : Март 03, 2010, 01:37 »

Всё тоже самое, что ты сейчас написал происходит в QSharedMemory::lock(). А lock() у него на базе QSystemSemaphore (interprocess). Но как я понял человек хотел, чтобы event от ОС пришел "типа поменялось". А с семафорами выходит другая незадача. Один висит в lock'e дожидаясь пока ему освободят ресурс и вроде бы всё хорошо, а вот второму этот ресурс может быть нафиг не нужен, так как команды от пользователя не поступило и сидит ждет в каком-нибудь QEvenLoop сигнала из GUI например или из БД. При этом если связь между процессами нужна двухсторонняя, то уже хрен. А из этого вытекает, что клиент и сервер должны быть разными приложениями, вместо того, чтобы сделать их идентичными и полноправными.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Март 03, 2010, 03:01 »

Но как я понял человек хотел, чтобы event от ОС пришел "типа поменялось".
Что человек хочет - это его дело. А моя задача была максимально быстрый обмен данными между 2 процессами (32 и 64 бит) - вот и пришлось крутить через shared memory.
Записан
JayFOX
Гость
« Ответ #13 : Март 04, 2010, 20:48 »

События изменения памяти можно получить через api, но это в ситуации и создания памяти через api (fileMapping), но QSharedMemory не даст доступ не qt-приложениям. Вопрос - тогда можно-ли сообщить другому процессу что-либо (например то, что мы изменили память), средствами qt?
Записан
SABROG
Гость
« Ответ #14 : Март 04, 2010, 20:54 »

QLocalSocket (named pipe), создан как-раз для IPC.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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