Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: Termit от Январь 23, 2015, 11:48



Название: Разделяемая память между процессами
Отправлено: Termit от Январь 23, 2015, 11:48
Всем привет.
Хочу странного :) Подскажите возможно ли

Суть такая есть два приложения которые между собой общаются по D-BUS. Оба хранят в себе копию одного и того же объекта. Состояние этого объекта синхронизируется через события отправляемые через этот самый D-BUS.

Чтобы быть ближе к теме расскажу немного подробней. Объект о котором идет речь - это товарный чек с набором товаров, дисконтной карточкой и прочими атрибутами. Приложения: одно демон который отвечает за запись в базу данных и работу с периферийным оборудованием, другое условно назовем его графический интерфейс который отображает этот чек.

Сам чек в процессе эволюции все усложняется и усложняется... Держать его в синхронном состоянии становится соответственно сложнее и сложнее, хотя для графического интерфейса достаточно было бы только доступа на чтение к этому объекту.

Может быть и устроила такая ситуация, если бы не захотелось работать одновременно с несколькими чекми, ну скажем с QMap-ом этих объектов. Синхронизировать это все дело будет еще той задачей...

Что хотелось бы: иметь возможность из графического приложения читать тот чек или тот набор чеков который живет в приложении-демоне.

Я читал о QSharedMemory. Насколько я понял со сложными типами там не все гладко: мне нужно по-любому делать сериализацию/десериалиацию своих классов при каждом чтении/записи, нужно знать размер сериализованных данных. Короче получится много накладных расходов, если не в процессе выполнения (что тоже может быть), то в процессе написания кода точно. А хотелось бы обойтись малой кровью.

Теперь после вступления сам вопрос: если ли способы разделить между двумя приложениями область памяти таким образом чтобы оттуда читался указатель на объект и чтобы с этим объектом можно было делать необходимые манипуляции? Может я неправильно понял суть QSharedMemory?

Наставьте на путь истинный.


Название: Re: Разделяемая память между процессами
Отправлено: Пантер от Январь 23, 2015, 11:51
QSharedMemory для этого и предназначен, вроде бы. Не юзал его, но void * QSharedMemory::​data можно кастить к любому классу и читать/писать его.


Название: Re: Разделяемая память между процессами
Отправлено: Termit от Январь 23, 2015, 13:14
Вроде так.
Я так понимаю, что для того чтобы получить "void * QSharedMemory::​data" нужно сначала реализовать в своем классе методы << и >>. По крайней мере так идет работа с QImage в примере. Да и метод create первым параметром требует размер.



Название: Re: Разделяемая память между процессами
Отправлено: Пантер от Январь 23, 2015, 13:50
Тебе дана область памяти, в которую ты можешь что угодно и как угодно писать. Глянь тут еще http://developer.nokia.com/community/wiki/QSharedMemory_example


Название: Re: Разделяемая память между процессами
Отправлено: Termit от Январь 23, 2015, 14:31
Посмотрел. Мало чем отличается от того, что есть в примерах.
Попытаюсь сделать небольшой проект поэкспериментировать.

Мне вот интересно, чисто теоретически, а как будет работать сериализация/десериализация такого члена класса как m_rows в примере ниже.
Код
C++ (Qt)
class CheckInfo
{
public:
...
private:
   QList<CheckRow*> m_rows;
 
Или нужно будет внутри класса отказаться от указателей?


Название: Re: Разделяемая память между процессами
Отправлено: Пантер от Январь 23, 2015, 15:16
Как хочешь, так и сериализуй. Это тоже самое, что в тот же файл сохранять. Читай про сериализацию в Qt.


Название: Re: Разделяемая память между процессами
Отправлено: xokc от Январь 23, 2015, 15:58
Если таких объектов много, то может проще какой нибудь in-memory embedded no-sql БД прикрутить? Типа level-db или kyoto protocol.


Название: Re: Разделяемая память между процессами
Отправлено: Termit от Январь 23, 2015, 16:02
Как хочешь, так и сериализуй. Это тоже самое, что в тот же файл сохранять. Читай про сериализацию в Qt.

Уже читаю. Даже делаю тестовый примерчик.

Ну да, так и получается, что я записываю все в QDataStream и оттуда же читаю. В итоге QSharedMemory и является тем же файлом только живет в памяти и ограничивает доступ к себе чтобы избежать одновременной записи из разных процессов.


Название: Re: Разделяемая память между процессами
Отправлено: Termit от Январь 23, 2015, 16:03
Если таких объектов много, то может проще какой нибудь in-memory embedded no-sql БД прикрутить? Типа level-db или kyoto protocol.

Так все равно будет сериализация/десериализация. И не будет контроля доступа.


Название: Re: Разделяемая память между процессами
Отправлено: xokc от Январь 24, 2015, 00:45
Так все равно будет сериализация/десериализация. И не будет контроля доступа.
Ручная сериализация, конечно, будет. Про отсутствие какого именно контроля идет речь не понял. Зато будет:
- потоко/процессо безопасность;
- эффективность добавления/удаления объектов (как по скорости, так и по памяти);
- оповещения об изменении данных;
- быстрый и гибкий поиск и прочие "плюшки".
Подчеркну ещё раз - "если таких объектов много".


Название: Re: Разделяемая память между процессами
Отправлено: Termit от Январь 24, 2015, 15:01
Создал небольшой проект, поигрался, все понял.

Изначально немного не так представлял себе работу QSharedMemory.

Всем спасибо. Вопрос для себя я закрыл.
Осталось только прикрутить к своему проекту и уже на реальных данных погонять. :)


Название: Re: Разделяемая память между процессами
Отправлено: kuzulis от Январь 24, 2015, 20:50
Цитировать
- оповещения об изменении данных;

Стоп, а как это реализуется? Ведь там нет сигналов которые уведомляют о том что данные были изменены и прочее..


Название: Re: Разделяемая память между процессами
Отправлено: Termit от Январь 25, 2015, 00:35
Цитировать
- оповещения об изменении данных;

Стоп, а как это реализуется? Ведь там нет сигналов которые уведомляют о том что данные были изменены и прочее..


Это зависит от самой СУБД. Можно получать уведомления о изменении через
Код
C++ (Qt)
bool QSqlDriver::subscribeToNotification ( const QString & name )
и
Код
C++ (Qt)
void notification ( const QString & name )

Не знаю умеют ли указанные СУБД такое, но ИМХО делать нужно так.


Название: Re: Разделяемая память между процессами
Отправлено: kuzulis от Январь 25, 2015, 14:41
Ах, если СУБД - то да.. Я имел ввиду нотификации из самих QSharedMemory..


Название: Re: Разделяемая память между процессами
Отправлено: Igors от Январь 26, 2015, 10:54
Ах, если СУБД - то да.. Я имел ввиду нотификации из самих QSharedMemory..
Делать самому, напр на QSystemSemaphore, там несложно

Создал небольшой проект, поигрался, все понял.

Изначально немного не так представлял себе работу QSharedMemory.

Всем спасибо. Вопрос для себя я закрыл.
Осталось только прикрутить к своему проекту и уже на реальных данных погонять. :)
Судя по начальному посту Вы и так понимали все верно - да, в shared хранить или простые структуры или сериализовать. Та что же изменилось?  :)


Название: Re: Разделяемая память между процессами
Отправлено: Termit от Январь 28, 2015, 19:28
Судя по начальному посту Вы и так понимали все верно - да, в shared хранить или простые структуры или сериализовать. Та что же изменилось?  :)

Это были больше предположения чем использование этого механизма.
Хотелось как я и писал "странного" нечто типа такого, чтобы между процессами просто передавать указатель на область памяти без лишних действий.
Потом помедитировал, сделал небольшой тест, наступило просветление. :)