Исключение C ++ Builder 2010 Dead Lock? - PullRequest
2 голосов
/ 21 марта 2010

Это какой-то исключительный замок, с которым я сталкиваюсь? Как этого избежать?

Посмотрите на нижнюю строку, где у меня есть объекты TIdContext подключенных клиентов, хранящиеся в объекте objlist, и иногда мне нужно обрабатывать его. Но если один пользователь отключен, в то время как другой поток обрабатывает список, то для этого освобожденного объекта TIdContext-> Data я получаю доступ Access, хорошо, я использую try / catch, но проблема в том, что в строке ниже есть какая-то мертвая блокировка и процесс зависает, если я присоединяю отладчик, он показывает Access voilation снова и снова и снова, и из-за этой исключительной блокировки увеличивается потребление процессора.

AnsiString UserID = ((Tmyobject*) ((TIdContext*) ObjList->Objects[i])->Data)->UserID;

я знаю, что могу проверить, прежде чем получить доступ к объекту, если объект не является нулевым, он работает .. Но мой вопрос заключается в том, что если однажды в синей луне объект данных будет освобожден в тот момент, когда выполняется проверка NULL, и в следующем линия, когда я снова получаю доступ к объекту, я получаю такую ​​же мертвую блокировку ???

Так, как избежать / обработать это исключение мертвой блокировки?

Вот стек вызовов ...

:005F07C0 System::AnsiStringBase::AnsiStringBase(this=:0285FCE0, src=????)
:0040223F System::AnsiStringT<0>::AnsiStringT<0>(this=:0285FCE0, src=:00000008)
:00457996 TSomeClass::SomeFunction(this=:009D8230, UserID={  }, DataSize={  }, )
:0047BFF1 __linkproc__ ThreadProc(Thread=:009561C0)
:004AD00E __linkproc__ ThreadWrapper(Parameter=:009EAA30)
:7c80b729 ; C:\WINDOWS\system32\kernel32.dll

Пожалуйста, помогитеppppppppppppppppppppp

Спасибо

Ответы [ 2 ]

2 голосов
/ 23 марта 2010

Не используйте try / catch для борьбы с нарушениями доступа. Это не Java NullPointerException, try / catch не может справиться с хаосом, который они наносят. Вместо этого исправьте основную ошибку.

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

Стандартный способ борьбы с условием состязания заключается в том, чтобы установить некоторый вид блокировки вокруг всего кода, который использует оспариваемый ресурс, чтобы потоки, использующие его, вежливо сменялись друг против друга, вместо того чтобы гоняться друг с другом. Читайте о мьютексах: они простые примитивы синхронизации, но, вероятно, достаточно мощные, чтобы решить вашу проблему.

1 голос
/ 25 марта 2010

Свойство Contexts в TIdTCPServer является потокобезопасным TThreadList, поэтому вы должны иметь возможность использовать LockList / UnlockList для итерации по активным контекстам без изменения сервером тем временем. Если вы ведете отдельный список, есть несколько вариантов, но вам придется опубликовать немного больше кода, описывающего, как вы добавляете / удаляете из этого списка.

...