Здравствуйте, Alexander G, Вы писали:
AG>Один тред запускает другой тред для выполнения долгой операции и периодически опрашивает флаг завершения.
AG>При установке флага — получает результаты.
А вот с "получает результаты" заминочка. Предложенный вариант не будет работать, т.к. weak_ptr<>::expired() не передаёт видимость данных между потоками, которые освободили ассоциированный shared_ptr, и потоком которому expired() вернул true (кто-то обещал?).
Это можно видеть например в sp_counted_base_gcc_sparc.hpp:
long sp_counted_base::use_count() const // nothrow
{
return const_cast< int32_t const volatile & >( use_count_ );
}
inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ )
{
__asm__ __volatile__( "cas %0, %2, %1"
: "+m" (*dest_), "+r" (swap_)
: "r" (compare_)
: "memory" );
return swap_;
}
Более корректно будет использовать поллинг напрямую завершения потока — обозрение завершения потока гарантирует передачу видимости над всеми данными:
case WM_TIMER:
if (worker.timed_join(0))
{
OperationComplete();
}
Да и вообще необходимость использования поллинга как-то смущает, почему не сделать просто:
boost::thread worker ([]()
{
lengthy_work(...);
PostMessage(current_thread_id, WM_WORK_ACCOMPLISHED, work_id, 0);
});