Здравствуйте, NKZ, Вы писали:
NKZ>А какие ошибки? Здесь тестовый проект для VS 2005, проверил, все вроде работает.
Извини — это я что-то не то сделал. Вроде собралось.
Только 2 вопроса
1. Зачем реализацию выносить в отдельный файл
2. Меня смущает временный контейнер в методе save_queue. Ведь семантика queue подразумевает уничтожение объекта при доступе к нему. Полезно ли это или все-таки при сериализации нужно разрушать прочитанные данные ?
Здравствуйте, k732, Вы писали:
K>1. Зачем реализацию выносить в отдельный файл
В принципе не обязательно, я просто переделал исходные бустовские файлы, а у них разнесено по разным файлам (правда там обобщенная имплементация save/load collection)
K>2. Меня смущает временный контейнер в методе save_queue. Ведь семантика queue подразумевает уничтожение объекта при доступе к нему. Полезно ли это или все-таки при сериализации нужно разрушать прочитанные данные ?
В общем случае void save_queue(Archive & ar, const Container &s) тоже самое что и void save_collection(Archive & ar, const Container &s) в бусте, подразумевается, что при сериализации контейнер не модифицируется.
А так все зависит от твоих требований к очереди, например
1. При остановке обработки ты должен сериализовать очередь, а при старте прочитать и обработать. В этом случае можно(но не обязательно), разрушать очередь.
2. Либо серилизовать данные в процессе обработки, например отсылать их для другим модулям для нотификации об изменений данных, тогда не надо разрушать.
3. что-нить еще
Здравствуйте, NKZ, Вы писали:
NKZ>В общем случае void save_queue(Archive & ar, const Container &s) тоже самое что и void save_collection(Archive & ar, const Container &s) в бусте, подразумевается, что при сериализации контейнер не модифицируется.
логично. согласен.
NKZ>А так все зависит от твоих требований к очереди, например NKZ> 1. При остановке обработки ты должен сериализовать очередь, а при старте прочитать и обработать. В этом случае можно(но не обязательно), разрушать очередь.
ну лучше тогда придерживаться принятой сигнатуры.
NKZ> 2. Либо серилизовать данные в процессе обработки, например отсылать их для другим модулям для нотификации об изменений данных, тогда не надо разрушать.
Тут вся проблемма в том, что данные помещаются в очередь несколькими писателями. Естественно синхронизировано.
Но в процессе этих действий читатель запрашивает данные для обработки. Тут синхронизация в самом методе сериализации (archive). Если я не буду подчищать очередь в просессе сериализации, то потом мне все равно нужно ее почистить т.к. она имеет ограничение по размеру, а отправленные данные мне больше не нужны. Если же я буду чистить очередь сразу, то отойду от принятой бустовской сигнатуры.
Разниза лишь в том, что в первом случае мне придется выполнять копирование, а после очистку, что может быть накладно, т.к. ограничена 50000 объектов, а во втором случа придется только очищать ее в процессе, что избавляет от копирования.
Это операция критична ко времени, поэтому тут делема.... Как лучше поступить ?
Здравствуйте, k732, Вы писали:
K>Тут вся проблемма в том, что данные помещаются в очередь несколькими писателями. Естественно синхронизировано. K>Но в процессе этих действий читатель запрашивает данные для обработки. Тут синхронизация в самом методе сериализации (archive). Если я не буду подчищать очередь в просессе сериализации, то потом мне все равно нужно ее почистить т.к. она имеет ограничение по размеру, а отправленные данные мне больше не нужны. Если же я буду чистить очередь сразу, то отойду от принятой бустовской сигнатуры.
K>Разниза лишь в том, что в первом случае мне придется выполнять копирование, а после очистку, что может быть накладно, т.к. ограничена 50000 объектов, а во втором случа придется только очищать ее в процессе, что избавляет от копирования.
K>Это операция критична ко времени, поэтому тут делема.... Как лучше поступить ?
Я не совсем понял, очередь сериализуется и сериализованные данные отдаются читателям и очередь очишается?
В любом случае, надо исходить из эффективности и требований к реализации, так что сигнатуры методов в бусте не являются истинной в последней инстанции . Еще как менее эффективный вариант, можно очищать очередь в синхронизированном блоке кода, сразу после сериализации.
Здравствуйте, NKZ, Вы писали: NKZ>Я не совсем понял, очередь сериализуется и сериализованные данные отдаются читателям и очередь очишается?
Очередь сериализуется. Полученные данные отправляются потзователю, а сама очередь подчищается, т.к. при сериализации создавалась ее копия. Тоесть данные после отправки не нужны в очереди.
NKZ>В любом случае, надо исходить из эффективности и требований к реализации, так что сигнатуры методов в бусте не являются истинной в последней инстанции . Еще как менее эффективный вариант, можно очищать очередь в синхронизированном блоке кода, сразу после сериализации.
Да, но тогда не избежать копирования...
З.Ы. Тут возникла еще одна проблемма, на которую я сначала не обратил внимания.
Т.к. очередь у меня синхронизирована, то методы добавления в очередь и извлечения из нее используют объекты синхронизации (мьютекс и семафор), которые я вляются членами-данными класса-очереди.
Естественно сериализовать объекты синхронизации нельзя. А если сериализовать только сам queue, то после десериализации
нельзя будет исподьзовать методы доступа к очереди, т.к. синхро-объекты будут не валидными.
Примерный код
Как можно с наименьшими усилиями выйти из этой ситуации ? Вводить метод для сериализации самого std::queue в
класс Queue не очень бы хотелось. Может дружественная функция иди еще что...
Здравствуйте, k732, Вы писали:
K>Очередь сериализуется. Полученные данные отправляются потзователю, а сама очередь подчищается, т.к. при сериализации создавалась ее копия. Тоесть данные после отправки не нужны в очереди.
Я думаю просто очищать очередь во время сериализации (метод закрыть мютексом). Вообщем убрать консантность и копирование в save_queue. Фиг с ним с бустом, так эффекивнее
K>З.Ы. Тут возникла еще одна проблемма, на которую я сначала не обратил внимания.
А вообще зачем сериализовать объекты синхронизации? Почему они будут невалидными?
Я уже запутался , я себе представляю алгоритм работы так
1. создаем инстанс класса очереди и загружаем сериализованные данные (только саму очередь, синхро-объекты инициализируются по умолчанию)
2. читатели читают (или нет???), писатели пишут
3. в любой момент времени можно сериализовать очередь(тоже нет проблем т.к метод синхронизируется), очередь очищается.
Если возможна ситуация когда, мы загружаем сериализованные данные во время работы (п.2), то нужен еще один синхронизационный объект, что бы лочить данные во время загрузки.
Видимо я просто не до конца понимаю ваш алгоритм работы с сериализованными данными, когда они нужны и кому (и нужны ли вообще, потому что после того, как очередь изменится они станут невалидными).
Здравствуйте, NKZ, Вы писали:
NKZ>Я думаю просто очищать очередь во время сериализации (метод закрыть мютексом). Вообщем убрать консантность и копирование в save_queue. Фиг с ним с бустом, так эффекивнее
понятно
NKZ>А вообще зачем сериализовать объекты синхронизации? Почему они будут невалидными?
А как будет инициализирован семафор ? ведь од изменяет свое состояние мотодами push и pop. А тут сериализация минует эти методы
NKZ>Видимо я просто не до конца понимаю ваш алгоритм работы с сериализованными данными, когда они нужны и кому (и нужны ли вообще, потому что после того, как очередь изменится они станут невалидными).
Вот пример (на непонятные типы не обращай внимания — думаю суть будет понятна)
Например LimitQueue и организована на std::queue
Пусть семафор имеет 30 свободных состояний.
В этот момент происходит сериализация. Очередь чистится.
1.Очистка очереди не может осуществляться методом pop, т.к. произойдет дедлок. Тоесть после очистки нужно еще сбросить семафор.
2. На друго стороне произошла десериализация. Какое состояние имеет семафор ? кто его будет инициализировать ?
Тоесть получается что его инициализация обязательно должна быть в методе сериализации
Здравствуйте, k732, Вы писали:
K>Пусть семафор имеет 30 свободных состояний. K>В этот момент происходит сериализация. Очередь чистится.
K>1.Очистка очереди не может осуществляться методом pop, т.к. произойдет дедлок. Тоесть после очистки нужно еще сбросить семафор. K>2. На друго стороне произошла десериализация. Какое состояние имеет семафор ? кто его будет инициализировать ? K>Тоесть получается что его инициализация обязательно должна быть в методе сериализации
1.да надо сбрасывать при сериализации и устанавливать queue.size() при десериализации.
2.да так оно и есть, при сериализаций/десериализаций, дожидаемся когда потоки закончат работать с данными, лочим данные и загружаем/сохраням очередь и инициализируем семафор(при загрузке данных) .