Здравствуйте, szag, Вы писали:
S>Есть unique_ptr<T> ptr который проверяется S>
S>if(ptr)
ptr->>foo();
S>
S>Это все происходит в потоке 1 S>в потоке 2 в какой-то момент происходит S>
S>ptr.reset(new T());
S>
S>очень не хочется юзать мютекс, так как инициализация происходит только один раз в потоке 2
Если задача единорозовая (т.е. обект создается только один раз), тогда можно завести атомарный bool (на x86/64 достаточно volitile bool) и проверяем его, а не потенциально опасный объект.
Если же объект пересоздается более одного раза, то тут наверное без shared_lock не обойтись (ну или городить огород с двухфаторной проверкой)
Здравствуйте, szag, Вы писали:
S>очень не хочется юзать мютекс, так как инициализация происходит только один раз в потоке 2
у вас есть какие-то проблемы при текущем подходе без мьютекса? это не легально (все же мьютекс по стандарту нужен), но по факту проблемы могут не проявиться
опишите подробнее
Здравствуйте, uzhas, Вы писали:
U>у вас есть какие-то проблемы при текущем подходе без мьютекса? это не легально (все же мьютекс по стандарту нужен), но по факту проблемы могут не проявиться U>опишите подробнее
проблема потенциальная, но она есть. У нас есть куча киентских сессий, который создаются когда к нам коннектится клиент. Мы им делаем рассылку данных. Часть данных идет в плагины, а они инициализируются в своих потоках в каждой сессии. Соответственно сейчас там стоит такой код
void handler(const data_type& data)
{
if (ptr)
ptr->set_data(data);
}
а в другом потоке происходит загрузка плагина (как раз вот этого ptr) и как только он загружен делается
ptr.reset(plugin_raw_ptr);
понятно, что может иногда падать. Объект ptr создается один раз за время жизни сессии и никогда не меняется.
Как исправить не атомарно понятно, хотелось бы как-то атомарно и попроще.
Здравствуйте, szag, Вы писали:
S>проблема потенциальная
то есть с проблемой вы еще не столкнулись. и я сомневаюсь, что столкнетесь
S>Как исправить не атомарно понятно, хотелось бы как-то атомарно и попроще.
просто — прикрыть мьютексом. только new лучше не вызывать под мьютексом, может привести к колизиям и уходу в ядро. без колизий не будет ухода в ядро и будет довольно дешево. вызывать метод у объекта тоже лучше не под мьютексом, но тут надо быть аккуратным с владением объекта
std::unique_ptr<T> data;
Mutex m;
//used writer threadvoid init()
{
std::unique_ptr<T> v(new T()); ; // new not under mutexif (rawInit(v.get()))
{
v.release();
}
}
bool rawInit(T* v)
{
MutexLock lock(m);
if (data)
return false;
data.reset(v);
return true;
}
//reader thread
T* getData()
{
MutexLock lock(m);
return data.get();
}
void useData()
{
if (T* v = getData())
{
v->foo();
}
}
Здравствуйте, szag, Вы писали:
U>>у вас есть какие-то проблемы при текущем подходе без мьютекса? это не легально (все же мьютекс по стандарту нужен), но по факту проблемы могут не проявиться U>>опишите подробнее S>проблема потенциальная, но она есть. У нас есть куча киентских сессий, который создаются когда к нам коннектится клиент. Мы им делаем рассылку данных. Часть данных идет в плагины, а они инициализируются в своих потоках в каждой сессии. Соответственно сейчас там стоит такой код
Т.е. хендлер может выполняться на неинициализированном плагине? Ну тогда это уже не код а дизайн плохой. Пока полная загрузка не пройдёт никакие обработчики вообще не должны вызываться. Кладите данные в очередь и ждите пока не пройдёт загрузка.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]