2010-03-20 65 views
2

这是我面临的某种异常死锁吗?如何避免它?C + + Builder 2010异常死锁?

看看下面的代码行,我将TIdContext对象存储在一个objlist中,有时我需要处理它。但是,如果一个用户断开连接,而另一个线程正在处理列表,那么为了释放TIdContext-> Data对象,我得到了Access voilation,好吧,它很好,我正在使用try/catch,但问题是,在下面的行有某种死锁和进程挂起,如果我附加一个debuger它显示访问voilation再次,再次和cpu coonsumption由于异常死锁上升。

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 

请helppppppppppppppppppppp

感谢

+1

C++ Builder是邪恶的!对不起,我只是说:]。 – pajton 2010-03-21 00:06:22

+1

顺便说一句,try/catch's用于捕获C++异常,而不是访问冲突。 – 2010-03-21 11:52:39

回答

2

不要使用try/catch来处理访问冲突。这些不是Java NullPointerExceptions,try/catch无法解决它们造成的破坏。改正底层错误。

A deadlock是当两个或更多线程永久卡住,等待另一个人做某事。你有什么是race condition:一个线程正在更新对象列表,而另一个正在尝试使用它,并且如果第一个线程完成得太快,它可能会无意中破坏第二个线程。

处理竞争条件的标准方法是在使用争用资源的所有代码周围放置某种锁,以便线程有条不紊地使用它,而不是彼此竞争。阅读互斥体:它们是一个简单的同步原语,但可能足以解决您的问题。

1

TIdTCPServer的Contexts属性是一个线程安全的TThreadList,因此您应该可以使用LockList/UnlockList来遍历活动的上下文,而服务器不会在此期间更改它们。如果你维护一个单独的列表,有几个选项,但你必须发布更多的代码来描述你如何添加到列表中或从列表中删除。

+0

是的,请使用服务器的内置客户端列表,不要单独管理您自己的客户端列表。在连接/断开连接期间,它们可能很容易失去同步。 – 2010-04-14 20:27:00