这是我遇到的某种例外死锁吗?如何避免呢?
看看下面的行,其中我有一个存储在objlist中的连接客户端的TIdContext对象,有时我需要处理它。但是如果一个用户断开而另一个线程正在处理列表,那么对于那个已释放的TIdContext->数据对象我正在获取Access语音,好吧我很好用我试用/ catch但问题是在下面的行有一些死锁和进程挂起,如果我附加一个debuger它显示访问声音再次和再次和再次,并且cpu coonsumption由于该异常死锁而上升。
AnsiString UserID = ((Tmyobject*) ((TIdContext*) ObjList->Objects[i])->Data)->UserID;
我知道我可以在访问对象之前检查,如果对象不是Null,它可以工作..但我的问题是,如果在蓝色的月亮中,当执行NULL检查时在下一个点释放Data对象当我再次访问该对象时,我得到相同的死锁???
那么如何避免/处理这种死锁异常?
这是调用堆栈......
: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
请helppppppppppppppppppppppp
由于
答案 0 :(得分:2)
不要使用try / catch来处理访问冲突。这些不是Java NullPointerExceptions,try / catch无法处理它们造成的破坏。修复底层错误。
deadlock是指两个或多个线程永远陷入困境,等待彼此做某事。你拥有的是race condition:一个线程正在更新对象列表,而另一个线程正在尝试使用它,如果第一个线程完成得太快,它可能会无意中破坏第二个线程。
处理竞争条件的标准方法是在使用竞争资源的所有代码周围放置一些锁,以便使用它的线程礼貌地轮流而不是彼此竞争。阅读互斥体:它们是一个简单的同步原语,但可能足以解决您的问题。
答案 1 :(得分:1)
TIdTCPServer的Contexts属性是一个线程安全的TThreadList,因此您应该能够使用LockList / UnlockList迭代活动上下文,同时服务器不会更改它们。如果您要维护一个单独的列表,则有几个选项,但您必须发布更多代码来描述如何从该列表中添加/删除。