Mat*_*ini 1 delphi multithreading
这是释放TCriticalSection在 Delphi 初始化部分中创建的对象的正确方法吗?
initialization
FPoolingCS := TCriticalSection.Create;
Run Code Online (Sandbox Code Playgroud)
finalization
FPoolingCS.Acquire;
FreeAndNil(FPoolingCS);
Run Code Online (Sandbox Code Playgroud)
我应该Release在Free?之前调用该方法?
该Acquire方法是否会抛出一些我需要处理的异常?
由于多种原因,这不是释放临界区的正确方法。
如果临界区的等待操作超时,此函数可以引发 EXCEPTION_POSSIBLE_DEADLOCK。超时间隔由以下注册表值指定:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\CriticalSectionTimeout。不处理可能的死锁异常;相反,调试应用程序。
如果一个临界区在它仍然拥有时被删除,则等待被删除临界区所有权的线程的状态是未定义的。
当进程退出时,如果对 EnterCriticalSection 的调用会阻塞,它将立即终止进程。这可能会导致无法调用全局析构函数。
调用FPoolingCS.AcquireWindows平台上调用EnterCriticalSection函数。所以第一个问题,获取临界区是否会引发异常,答案是肯定的。
同样根据文档,您不应该尝试处理此类异常,但您必须调试应用程序,因为问题的根源在于其他一些代码。
但是,Acquire在任何平台上释放临界区实例之前不应调用的最显着原因是,如果此时有一些其他线程正在执行某些工作并依赖该临界区,则意味着您的关闭和清理过程已完全中断. 换句话说,如果Acquire解决了你的问题,真正的问题是在另一个城堡中,而你并没有真正解决任何问题,你只是稍微改变了动态,这可能有效也可能无效,这取决于所涉及的所有其他代码。
出于同样的原因,调用ReleasebeforeFree将毫无意义。如果还有其他相关线程仍在运行,它们可能会在Free执行之前获取锁。
只需调用Free关键部分,或者如果您喜欢使用FreeAndNil,如果您的关闭过程被破坏,最终会崩溃。请记住,线程问题不能始终如一地重现,因此没有崩溃仍然并不意味着您的代码完全没有错误。
| 归档时间: |
|
| 查看次数: |
131 次 |
| 最近记录: |