Re: Ещё одно применение shared_ptr
От: remark Россия http://www.1024cores.net/
Дата: 26.12.09 14:32
Оценка: 50 (3)
Здравствуйте, 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);
});



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.