Delphi DLL - 线程安全

时间:2011-04-15 13:08:25

标签: multithreading delphi dll

我有一个Delphi DLL,我想在我的应用程序内部加载一个线程(不止一个,准确地说)。 DLL只是创建一个对象,然后它使用它并销毁它。从这个角度来看,DLL代码是线程安全的。

但是如果我在一个线程中加载该DLL会发生什么? DLL仍然是线程安全的吗?关于加载DLL的线程,我应该知道什么?我已经看到VCL具有在创建线程时设置的IsMultThread属性,但是dll会得到关于此的通知,还是应该手动执行?

3 个答案:

答案 0 :(得分:11)

最常见的陷阱是使用全局变量。只要您不使用任何全局变量(或正确地同步访问您使用的变量),您将对线程安全有很长的路要走。

例如,内存管理器使用

IsMultiThread在单线程情况下进行优化。我个人认为这几天不值得优化,因为几乎所有有用的代码都有一些描述的线程。我只是在您的DLL开头将IsMultiThread设置为True,例如在您的DLL .dpr文件的begin / end块中,或者在您单元的一个初始化部分中,它们相同。

要直接回答您的问题,除非您在该DLL中创建线程,否则DLL中的IsMultiThread实例将不会设置为true。由于您在EXE中创建了线程,因此需要在DLL中自行完成。

更一般地说,在不知道代码的线程安全性以及线程安全的实际含义的情况下,根本不可能对代码的线程安全性说太多。后一点可能听起来很奇怪,但我所指的是Eric Lippert着名的What is this thing you call "thread safe"?文章中讨论的问题。

答案 1 :(得分:4)

IsMultiThread设置为True库项目主要块中的第一件事:

library MyLibrary;
begin
  IsMultiThread := True;
  ...
end.

这将指示内存管理器使用线程安全的分配/释放例程。

答案 2 :(得分:2)

如果你在线程中做什么都很小心,你会没事的。如果您需要更新主线程的VCL,请使用synchronize,或者更好,但不要。

我有一个很大的DLL,我在那里进行大量的数据库访问,并且它在一个线程中运行。在我的单元测试中,一切都运行得很好,但是当在主应用程序中的一个线程中运行时,它会高高飘扬。事实证明,我不得不重新阅读有关线程安全的数据库文档。在我的例子中,它是DBISAM,我只需要确保为线程数据库实例创建一个新会话,因此它不会与主要实例冲突。

我遇到麻烦的另一个地方(再次,在单元测试中工作得很好,在线程中失败)是使用XML处理。我必须在使用XML DOM之前/之后调用CoInitialize / CoUnInitialize。这适用于任何SOAP内容,它使用XML DOM。