【问题标题】:Is it safe to call a dll function from multiple threads in a single application?在单个应用程序中从多个线程调用 dll 函数是否安全?
【发布时间】:2009-04-11 07:26:17
【问题描述】:

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

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

【问题讨论】:

    标签: multithreading delphi dll


    【解决方案1】:

    简答:

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

    长答案:

    是否实际上可能取决于是否使用共享可变状态的 DLL 函数。

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

    DLL_SetUser(UserName, Password)
    if DLL_IsAuthenticated then
    begin
    ...
    end;
    

    那么从不同的线程中使用肯定是安全的。在此示例中,您不能保证在 DLL_SetUserDLL_IsAuthenticated 之间没有其他线程对 DLL_SetUser 进行不同的调用。

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

    if DLL_IsAuthenticated(UserName, Password) then
    begin
    ...
    end;
    

    但请注意:DLL 函数可能看起来是原子的,但在内部使用了某些东西,但事实并非如此。例如,如果 DLL 创建了一个始终具有相同名称的临时文件,或者它访问的数据库一次只能处理一个请求,则它被视为共享状态。 (抱歉,我想不出更好的例子)

    总结:

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

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

    【讨论】:

    • 另一个例子可能是一个内部数据结构,其中导出的函数添加和/或删除元素 - 例如(失败的)身份验证请求列表,或经过身份验证的用户列表。
    【解决方案2】:

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

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

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

    如果您的 DLL 允许完全独立地执行导出的函数,还请检查 threadvar 线程特定的变量。请注意,initializationfinalization 部分对他们来说是不可用的,但也许线程通知也可以帮助您。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        我不熟悉 Delphi 2009 身份验证 DLL 的工作原理。也许您应该将该信息添加到标题中(您正在专门讨论 Delphi 2009 DLL)

        【讨论】:

        • Win32 DLL 是可以在 Win32 中加载的任何 DLL。也许您的意思是“Windows 系统 DLL”?此外,Delphi 2009 没有“身份验证 DLL”之类的东西。这些必须是某种第三方 DLL。
        猜你喜欢
        • 1970-01-01
        • 2011-07-14
        • 1970-01-01
        • 1970-01-01
        • 2012-02-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多