Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 在单个应用程序中从多个线程调用dll函数安全吗?_Multithreading_Delphi_Dll - Fatal编程技术网

Multithreading 在单个应用程序中从多个线程调用dll函数安全吗?

Multithreading 在单个应用程序中从多个线程调用dll函数安全吗?,multithreading,delphi,dll,Multithreading,Delphi,Dll,我正在用Delphi2009编写一个服务器应用程序,它实现了几种类型的身份验证。每个身份验证方法都存储在单独的dll中。首次使用身份验证方法时,将加载相应的dll。dll仅在应用程序关闭时释放 在服务器线程(连接)之间不进行任何形式的同步的情况下访问DLL是否安全?如果您谈论的是Win32 DLL,那么如果由多个线程、应用程序调用,它们就意味着是安全的。我不知道你的DLL是做什么的,但是如果你的DLL使用了一个可锁定的资源,比如一个文件或一个端口,那么基于DLL内部的实现可能会有问题 我不熟悉D

我正在用Delphi2009编写一个服务器应用程序,它实现了几种类型的身份验证。每个身份验证方法都存储在单独的dll中。首次使用身份验证方法时,将加载相应的dll。dll仅在应用程序关闭时释放


在服务器线程(连接)之间不进行任何形式的同步的情况下访问DLL是否安全?

如果您谈论的是Win32 DLL,那么如果由多个线程、应用程序调用,它们就意味着是安全的。我不知道你的DLL是做什么的,但是如果你的DLL使用了一个可锁定的资源,比如一个文件或一个端口,那么基于DLL内部的实现可能会有问题


我不熟悉Delphi 2009认证DLL的工作。也许你应该把这些信息添加到标题中(你说的是Delphi 2009 DLL)

要使DLL具有线程安全性,您需要保护一个进程中的多个线程可以并发访问的所有共享数据结构-为DLL编写代码与为可执行文件编写代码之间没有区别

对于多个进程,并发访问没有风险,因为每个进程都有自己的DLL数据段,因此从不同的进程中看到相同名称的变量实际上是不同的。实际上,在DLL中提供来自不同进程的相同数据要困难得多,您基本上需要实现用于进程间数据交换的相同功能

请注意,DLL的特殊之处在于,当进程或线程连接到DLL或从DLL分离时,您会收到通知。有关说明以及如何在Delphi编写的DLL中使用此功能的示例,请参阅文档。因此,如果线程之间不是完全独立的(并且没有共享数据被写访问),那么您将需要一些具有同步访问的共享数据结构。各种通知可能会帮助您正确设置DLL中的任何数据结构


如果您的DLL允许完全独立地执行导出的函数,也请检查threadvar线程特定变量。请注意,对于它们来说,初始化和终结部分不可用,但线程通知可能也可以帮助您做到这一点。

问题是,如果您无法控制源代码(或说明它的文档),则不能假定DLL是线程安全的因此,您应该假设它不是

简短的回答:

是的,通常可以从多个线程调用DLL函数,因为每个线程都有自己的堆栈,调用DLL函数与调用自己代码中的任何其他函数大致相同

长答案:

是否可能取决于DLL函数是否使用共享可变状态

例如,如果您执行以下操作:

DLL_SetUser(UserName, Password)
if DLL_IsAuthenticated then
begin
...
end;
那么从不同的线程使用它肯定是不安全的。在本例中,您不能保证在
DLL\u SetUser
DLL\u之间没有其他线程对
DLL\u SetUser
进行不同的调用

但是,如果DLL函数不依赖于某种预定义的状态,即所有必要的参数一次可用,并且所有其他配置对于所有线程都是相同的,则可以假定它可以工作

if DLL_IsAuthenticated(UserName, Password) then
begin
...
end;
但要小心:DLL函数可能看起来像原子函数,但在内部使用的东西却不是原子函数。例如,如果DLL创建了一个始终具有相同名称的临时文件,或者它访问了一个一次只能处理一个请求的数据库,则它将被视为共享状态。(对不起,我想不出更好的例子了)

摘要:

如果DLL供应商说,他们的DLL是线程安全的,我会从多个线程使用它们,而不会锁定。如果他们不知道——或者即使供应商不知道——你应该谨慎行事,使用锁定


至少在遇到性能问题之前。在这种情况下,您可以尝试创建多个应用程序/进程来包装DLL调用并将其用作代理。

另一个示例可能是内部数据结构,其中导出的函数添加和/或删除元素,如(失败)身份验证请求的列表,或已验证用户的列表。Win32 DLL是可以在Win32中加载的任何DLL。也许你指的是“Windows系统DLL”?此外,Delphi2009没有任何“身份验证DLL”之类的东西。这些必须是某种类型的第三方DLL。