MFC / CCriticalSection: зависает простая ситуация блокировки - PullRequest
0 голосов
/ 08 апреля 2010

Мне нужно запрограммировать простую многопоточную программу на MFC / C ++ для универсального назначения.

У меня есть простой сценарий, в котором у меня есть рабочий поток, который выполняет функцию следующим образом:

UINT createSchedules(LPVOID param)
{
  genProgThreadVal* v = (genProgThreadVal*) param;
  // v->searcherLock is of type CcriticalSection*
  while(1)
  {
    if(v->searcherLock->Lock())
    {
      //do the stuff, access shared object , exit clause etc..
      v->searcherLock->Unlock();
    }
  }
  PostMessage(v->hwnd, WM_USER_THREAD_FINISHED , 0,0);
  delete v;
  return 0;
}

В моем основном классе пользовательского интерфейса у меня есть CListControl, который я хочу иметь доступ к общему объекту (типа std :: List). Отсюда и материал для блокировки. Итак, этот CList имеет функцию-обработчик, которая выглядит следующим образом:

void Ccreationprogramme::OnLvnItemchangedList5(NMHDR *pNMHDR, LRESULT *pResult)
{
  LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
  if((pNMLV->uChanged & LVIF_STATE) 
    && (pNMLV->uNewState & LVNI_SELECTED))
  {    
    searcherLock.Lock();
    // do the stuff on shared object
    searcherLock.Unlock();

    // do some more stuff
  }
  *pResult = 0;
}

SearcherLock в обеих функциях - это один и тот же объект. В функцию рабочего потока передается указатель на объект CCriticalSection, который является членом моего диалогового класса.

Все работает, но, как только я нажимаю на мой список и, таким образом, запускаю функцию-обработчик, вся программа зависает на неопределенное время. Я попытался использовать обтекание CSingleLock над объектом критической секции, и ничего из этого не сработало. Чего мне не хватает?

РЕДАКТИРОВАТЬ: Я нашел решение, благодаря удивительной проницательности Франси. Это научит меня не помещать каждый бит кода в вопрос. Спасибо!

Ответы [ 3 ]

5 голосов
/ 08 апреля 2010

Вы уверены, что фоновый поток не делает ничего, что SendMessage потоку пользовательского интерфейса между Lock и Unlock?

Если это произойдет, он будет заблокирован до сообщенияочередь обрабатывает это сообщение;однако очередь сообщений никогда не попадет в нее, поскольку она блокируется в середине обработки уведомления об изменении элемента в представлении списка.

0 голосов
/ 08 апреля 2010

Не видя каких-либо «вещей», происходящих в заблокированных регионах, трудно убедиться, что ваш код когда-нибудь появится из них.Пара предложений:

  1. Возможно, что ваш поток блокирует критическую секцию, затем делает что-то, что вызывает исключение, таким образом, завершается и не может разблокироваться.Убедитесь, что этого не произойдет, используя методы блокировки с областью действия.

  2. Возможно, что один из критических разделов просто не завершается.Войдите в систему с отладчиком и проверьте ожидаемое поведение.

0 голосов
/ 08 апреля 2010

Я заметил, что вы delete v; в createSchedules (). Почему?

Меня удивляет, действительно ли SearcherLock ссылается на один и тот же объект в обеих функциях. Если блокировка не находится в той же ячейке памяти, она, безусловно, не будет работать.

Кроме того, блокировки или критические секции должны быть инициализированы с надлежащим состоянием. Вы не показываете этот код, поэтому я не могу сказать. Но если вы не инициализировали его, он будет иметь плохое содержимое и обязательно сломается.

Выполните некоторую отладку, используя макросы TRACE (я думаю, это то, что вы используете в MSVC), чтобы вывести &searcherLock (расположение памяти searcherLock) в обеих функциях, чтобы гарантировать, что это один и тот же объект.

...