Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Рихтер Класс COptex 
:(
    Опции темы
Kuvaldis
Дата 2.3.2008, 12:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


механик-вредитель
***


Профиль
Группа: Участник Клуба
Сообщений: 1189
Регистрация: 16.6.2006
Где: Минск

Репутация: нет
Всего: 61



Всем привет! smile
В 4-м издании Рихтера есть реализация оптимизированного мьютекса. В реализации функций Enter есть вопрос:
Код

void COptex::Enter() 
{
   // Spin, trying to get the optex
   if (TryEnter()) 
   {
      return;  // We got it, return
   }

   // We couldn't get the optex, wait for it.
   DWORD dwThreadId = GetCurrentThreadId();

   if (InterlockedIncrement(&m_psi->m_lLockCount) == 1) 
   {
      // Optex is unowned, let this thread own it once
      m_psi->m_dwThreadId = dwThreadId;
      m_psi->m_lRecurseCount = 1;
   } 
   else 
   {
     //  !!!!!!  зачем этот if???  Ведь в TryEnter он проверяется 
      if (m_psi->m_dwThreadId == dwThreadId)             //  (1)
      {
         // If optex is owned by this thread, own it again
         m_psi->m_lRecurseCount++;
      } 
      else 
      {
         // Optex is owned by another thread, wait for it
         WaitForSingleObject(m_hevt, INFINITE);

         // Optex is unowned, let this thread own it once
         m_psi->m_dwThreadId = dwThreadId;
         m_psi->m_lRecurseCount = 1;
      }
   }
}


///////////////////////////////////////////////////////////////////////////////


BOOL COptex::TryEnter() 
{
   DWORD dwThreadId = GetCurrentThreadId();

   BOOL fThisThreadOwnsTheOptex = FALSE;     // Assume a thread owns the optex
   DWORD dwSpinCount = m_psi->m_dwSpinCount; // How many times to spin

   do 
   {
      // If lock count = 0, optex is unowned, we can own it
      fThisThreadOwnsTheOptex = (0 == InterlockedCompareExchange(&m_psi->m_lLockCount, 1, 0)); 

      if (fThisThreadOwnsTheOptex) 
      {
         // Optex is unowned, let this thread own it once
         m_psi->m_dwThreadId = dwThreadId;
         m_psi->m_lRecurseCount = 1;
      } 
      else 
      {
         if (m_psi->m_dwThreadId == dwThreadId)   //  (2)
         {
            // If optex is owned by this thread, own it again
            InterlockedIncrement(&m_psi->m_lLockCount);
            m_psi->m_lRecurseCount++;
            fThisThreadOwnsTheOptex = TRUE;
         }
      }

   } 
   while (!fThisThreadOwnsTheOptex && (dwSpinCount-- > 0));

   // Return whether or not this thread owns the optex
   return(fThisThreadOwnsTheOptex);
}


///////////////////////////////////////////////////////////////////////////////


Не очень ясно, зачем в Enter стоит блок (1), ведь в TryEnter() есть блок (2) smile 


--------------------
Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей
PM MAIL ICQ   Вверх
SergeCpp
Дата 9.3.2008, 14:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


 
**


Профиль
Группа: Участник
Сообщений: 955
Регистрация: 8.8.2005
Где: At Home

Репутация: 10
Всего: 124



Подсказка в девятой строке user posted image

Не очень ясна высказанная тут связь ("зачем" -> "ведь") между блоками 1 и 2 (это ещё подсказка)

Третья подсказка: детально опишите это "зачем" -> "ведь"

PM MAIL WWW ICQ   Вверх
Kuvaldis
Дата 9.3.2008, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


механик-вредитель
***


Профиль
Группа: Участник Клуба
Сообщений: 1189
Регистрация: 16.6.2006
Где: Минск

Репутация: нет
Всего: 61



SergeCpp, 
Если мы не получили мьютекс в TryEnter() то понятно, что блок 62-68 не отработал
Соотвественно, в 21-24 идет повторная проверка совпадения m_psi->m_dwThreadId == dwThreadId

МНе кажется, что данную проверку нужно использовать, если у нас нету спин-блокировки, т.е. когда в Enter() не вызывается TryEnter()

И еще, мы ж в строке 9 не ждем?.. Ожидаем только событие в 29?
Что-то я запутался :( 

Это сообщение отредактировал(а) Kuvaldis - 9.3.2008, 16:14


--------------------
Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей
PM MAIL ICQ   Вверх
korian
Дата 10.3.2008, 01:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 4
Всего: 17



Kuvaldis
кароче мало понимаю, что тут вообще происходит smile
но скажу что блок 1 блок 2 совсем не повторяються, если детальней рассматривать.
первых блок, если полностью расписать получаеться:
Код

if ((InterlockedIncrement(&m_psi->m_lLockCount) != 1) && (m_psi->m_dwThreadId == dwThreadId)) 
      {
         // If optex is owned by this thread, own it again
         m_psi->m_lRecurseCount++;
      } 

второй блок расписываем... получаеться:
Код

fThisThreadOwnsTheOptex = (0 == InterlockedCompareExchange(&m_psi->m_lLockCount, 1, 0)); 
         if (!fThisThreadOwnsTheOptex  && (m_psi->m_dwThreadId == dwThreadId))
         {
            // If optex is owned by this thread, own it again
            InterlockedIncrement(&m_psi->m_lLockCount);
            m_psi->m_lRecurseCount++;
            fThisThreadOwnsTheOptex = TRUE;
         }

я правда не знаю чем отличаются InterlockedIncrement от InterlockedCompareExchange... но видно чем-то существенным.

Добавлено через 5 минут и 48 секунд
к чему я это...
если выполняеться 2-й блок, то 1-й блок не выполняеться 100%, т.к. там
if (TryEnter()) 
   {
      return;  // We got it, return
   }
ну и предпологаю, что в обратную сторону тоже самое, если не выполняеться 2-й блок, выполняеться 1-й

PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0510 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.