![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() |
alexy |
![]()
Сообщение
#1
|
Студент ![]() Группа: Участник Сообщений: 44 Регистрация: 4.8.2010 Пользователь №: 1931 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
shared_ptr нельзя создать в конструкторе...
у меня сейчас в многопоточном коде часто появляются двухэтапные конструкторы. снчала создаешь shared_ptr потом вызываешь какой-нибудь registr или еще что-нибудь, куча отложенных созданий объектов, когда я бы мог создать его в конструкторе ,но создаю в фукнции ,которой он нужен, из-за этого появляются дополнительные проверки "не создал ли я его уже?", которых можно было бы избежать, если бы... к тому же мне не нравится shared_from_this с точки зрения ООП, это как бы деталь реализации, закравшаяся в интерфейс. может спасти intrusive_ptr, но у него нет weak_ptr и значит проблема циклических ссылок будет. вобщем сегодня я накатал такой код. не уверен в правильности использвания std::atomic. выбрал shared_ptr для быстроты реализации. потом хочу сделать структуру, одно поле будет счетчиком ссылок для объекта, другое для weak_ptr'а. выкладываю: может кому интересно или у кого-то уже есть свои проверенные наработки, лучше чем у меня, поделитесь пожалуйста. зы: а что, нельзя загружать файлы hpp ??
Прикрепленные файлы
|
|
|
![]() |
lanz |
![]()
Сообщение
#2
|
![]() Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 690 Регистрация: 28.12.2012 Пользователь №: 3660 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
1. При такой архитектуре вы можете удалить виджет из другого потока, создав его в одном. Фактически его удалит тот поток, который будет держать последний shared_ptr.
2. Обновлять данные из другого потока на виджете не безопасно. Вы уверенны что не придет событие отрисовки в середине вашего обновления? Для многопоточной работы лучше исползуйте систему сообщений. Т.е. другой поток постит сообщение для отображения, а виджет смотрит - есть у него такой потомок или нет. Если нет, ничего страшного, если есть - информация безопасно обновляется. Разделяемые между потоками данные - это большая мина, с которой надо очень аккуратно обходится. |
|
|
alexy |
![]()
Сообщение
#3
|
Студент ![]() Группа: Участник Сообщений: 44 Регистрация: 4.8.2010 Пользователь №: 1931 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
1. При такой архитектуре вы можете удалить виджет из другого потока, создав его в одном. Фактически его удалит тот поток, который будет держать последний shared_ptr. 2. Обновлять данные из другого потока на виджете не безопасно. Вы уверенны что не придет событие отрисовки в середине вашего обновления? Для многопоточной работы лучше исползуйте систему сообщений. Т.е. другой поток постит сообщение для отображения, а виджет смотрит - есть у него такой потомок или нет. Если нет, ничего страшного, если есть - информация безопасно обновляется. Разделяемые между потоками данные - это большая мина, с которой надо очень аккуратно обходится. 1. ну да.. а что в этом такого?
2. сам виджет thradsafe. то есть даже если придет, ничего страшного, максимум данные потеряются. ну, вообще, это сам пользователь если ступит. то есть виджет же не рисуется прямо на мониторе, он передается по сети, там, у клиента, только один поток. так что если он исправляет значение виджета, не дожидается ответа сервера и начинает что-то еще править, то.. ну это как нажать кнопку сохранить, потом еще текст начать править.. он ведь не сохранится, если не нажать еще раз. мне кажется с очередью сообщений труднее. сейчас у меня виджет содержит данные и мутекс, также функционал от widget_base - слабый казатель на родителя, который и так thread_safe сообщения они передают клиенту по thradsafe каналу, то есть там мутекс перед тем как оправить данные, так что пользователю каша не придет. кстати, не понял что-то функционала boost::intrusive_ptr если в конструкторе ему передать (some_raw_pointer, false). это же вызовет ошибку в деструкторе его. или intrusive_ptr_release нужно делать if(counter && --counter == 0) delete p; |
|
|
![]() ![]() ![]() |
![]() |
|
Текстовая версия | Сейчас: 12.6.2025, 19:58 |