Re[3]: Вопросы на собеседовании про многопоточность
От: Polonius Россия  
Дата: 25.05.11 06:26
Оценка: 3 (1) +3
Здравствуйте, Aleksey_NN, Вы писали:

A_N>Здравствуйте, shrecher, Вы писали:


S>>Простой вопрос: поддержка целостности объекта через счетчик ссылок как в COM-t. Написать методы AddRef, Release.


A_N>Обычно приводят что-то такое:


A_N>
A_N>void CReferenceCounter::AddRef( void ) {
A_N>  ::IntrlockedIncrement( &m_nReferences );
A_N>}

A_N>void CReferenceCounter::Release( void ) {
A_N>  if( !::IntrlockedDecrement( &m_nReferences ) ) {
A_N>  delete this;
A_N>  }
A_N>}
A_N>


A_N>Либо синхронизируют через критическую секцию. А мне вот интересно, тут безопасно разве удалять объект? Если бы синхронизировали критической секцией, она бы была мембером класса, как удалить объект? Выйти из нее — а может в это время другой поток addRef сделает, а потом текущий, думая что счетчик 0, уничтожит. Не выходить из нее тоже нельзя.

A_N>Да и тут примерно такая ситуация вроде может быть — зашли в аddRef, в это время другой поток декрементировал и стер объект, и тут мы дошли в первом поток до вызова IntrlockedIncrement(). Может так быть?

Здесь все просто, всего лишь нужно задуматься "а кто может делать AddRef" ?

Ответ : тот кто имеет "валидный" интерфейс/хэндл, то есть пока этот хэндл валидный,
объект не будет удален даже вызовом Release() из другого потока.
Т.е. объект будет удален при вызове Release() у последнего "валидного" хэндла.

Все это значит, чтобы передать "валидный" хэндл в другой поток, нужно сначала сделать ему AddRef()
и только потом передавать в др поток (тогда можно считать, что в новом потоке "валидный" хэндл).
Дайте мне точку входа, и я переверну мир.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.