Информация об изменениях

Сообщение Re[2]: thread_local in C++17 от 01.02.2023 10:18

Изменено 01.02.2023 10:21 Videoman

Re[2]: thread_local in C++17
Здравствуйте, vopl, Вы писали:

V>...


V>То есть, твоя догадка практически верна, любой odr-use в потоке требует наличия проинициализированного объекта, и компилятор это требование обеспечивает по факту odr-use


V>Как починить — хз, но плясать надо от того что надо как то сделать odr-use этого объекта в том потоке в котором он нужен.. Эта проблема несколько похожа на проблему динамических десериализаторов, у них из сети прилетают данные, из них десериализатор берет идентификатор и на его основе из мапы выбирает нужный процессор, далее отдает ему остаток данных. Вот их проблема — как сделать само-регистрирующийся в десериализаторе процессор. То есть, чтобы программист только написал код этого процессора, а он чик-чик сам бы в мапу записался. Там это решают на уровне static storage duration, а он инициализируется если есть побочные эффекты в конструкторе. Это легко обеспечить. В случае же thread_local внутренние побочные эффекты не уситываются для старта инициализации, нужно обязательно проявить активность снаружи объекта, сделать ему odr-use. И я так понимаю, что вариант явно ручками каждый такой thread_local потрогать в нужном потоке чтобы получилось odr-use — вовсе не вариант. Хз как это можно автоматизировать


Точно! На практике именно это и видно. На самом деле у меня такая проблема:
Есть самописанные сигналы-слоты. Для вызова слотов в каждом потоке есть очередь. Мной предполагалось что бы можно делать connect сигналов со слотами и опционально задавать bind к произвольному потоку, выбирая его очередь. Естественно очередь thread_local у каждого потока своя. Всё работало замечательно несколько лет, пока я не захотел вызвать connect сигнала в одном потоке, а дать bind слоту для другого. Предполагалось что очередь там уже будет готова к моменту вызова. А вот оказалось, что пока запускаемый поток не тронет очередь, её физически не будет и сигналы летят в никуда.

Выход конечно есть. "Трогать" очередь слотов в нужном потоке и таким образом создавать её. Но это как-то криво, на мой взгляд. Потом у меня решение работало в общем виде, с любыми потоками, не обязательно моими, а теперь не знаю как выкрутится из этой ситуации.
Re[2]: thread_local in C++17
Здравствуйте, vopl, Вы писали:

V>...


V>То есть, твоя догадка практически верна, любой odr-use в потоке требует наличия проинициализированного объекта, и компилятор это требование обеспечивает по факту odr-use


V>Как починить — хз, но плясать надо от того что надо как то сделать odr-use этого объекта в том потоке в котором он нужен.. Эта проблема несколько похожа на проблему динамических десериализаторов, у них из сети прилетают данные, из них десериализатор берет идентификатор и на его основе из мапы выбирает нужный процессор, далее отдает ему остаток данных. Вот их проблема — как сделать само-регистрирующийся в десериализаторе процессор. То есть, чтобы программист только написал код этого процессора, а он чик-чик сам бы в мапу записался. Там это решают на уровне static storage duration, а он инициализируется если есть побочные эффекты в конструкторе. Это легко обеспечить. В случае же thread_local внутренние побочные эффекты не уситываются для старта инициализации, нужно обязательно проявить активность снаружи объекта, сделать ему odr-use. И я так понимаю, что вариант явно ручками каждый такой thread_local потрогать в нужном потоке чтобы получилось odr-use — вовсе не вариант. Хз как это можно автоматизировать


Точно! На практике именно это и видно. На самом деле у меня такая проблема:
Есть самописанные сигналы-слоты. Для вызова слотов в каждом потоке есть очередь. Мной предполагалось, что бы можно делать connect сигналов со слотами и опционально задавать bind к произвольному потоку, выбирая его очередь. Естественно очередь thread_local у каждого потока своя. Всё работало замечательно несколько лет, пока я не захотел вызвать connect сигнала в одном потоке, а дать bind слоту для другого. Предполагалось, что очередь там уже будет готова к моменту вызова. А вот оказалось, что пока запускаемый поток не тронет очередь, её физически не будет и сигналы летят в никуда.

Выход конечно есть. "Трогать" очередь слотов в нужном потоке и таким образом создавать её. Но это как-то криво, на мой взгляд. Потом у меня решение работало в общем виде, с любыми потоками, не обязательно моими, а теперь не знаю как выкрутится из этой ситуации.