【问题标题】:DLL Mutex - an example [duplicate]DLL Mutex - 一个例子[重复]
【发布时间】:2011-01-02 17:50:52
【问题描述】:

可能重复:
DLL thread safety

我正在用 MS VS C++ express 编写一个 DLL 文件,该文件同时加载到多个客户端应用程序中,它与加载的 DLL 的其他实例使用共享内存。让我们假设 DLL 看起来像这样:

#include stdafx.h  
#pragma data_seg (".TEST")  
//Shared variables  
#pragma data_seg ()  
#pragma comment(linker, "/section:.TEST,RWS")  
_DLLAPI void __stdcall doCalc()  
{  
//Do critical stuff  
}

如果从两个或多个客户端同时调用doCalc,系统将崩溃。 如果该函数已经被调用,我将如何创建一个“停止”其他调用的互斥锁? 请举个例子,因为我在过去的两个小时里试图在互联网上找到一个像样的;)

提前致谢。

【问题讨论】:

    标签: c++ multithreading visual-c++ dll mutex


    【解决方案1】:

    每个进程的代码:

    // At the start of every process
    HANDLE sharedMemoryMutex = CreateMutex(NULL, FALSE, "My shared memory mutex");
    
    // When you want to access shared memory:
    DWORD dwWaitResult = WaitForSingleObject(sharedMemoryMutex, INFINITE);
    
    if (dwWaitResult == WAIT_OBJECT_0 || dwWaitResult == WAIT_ABANDONED)
    {
       if (dwWaitResult == WAIT_ABANDONED)
       {
          // Shared memory is maybe in inconsistent state because other program
          // crashed while holding the mutex. Check the memory for consistency
          ...
       }
    
       // Access your shared memory
       ...
    
       // After this line other processes can access shared memory
       ReleaseMutex(sharedMemoryMutex);
    }
    

    【讨论】:

    • 您还需要确保 1) 其他进程(在其他用户的上下文中运行)获得相同的互斥锁,以及 2) 其他进程也可以访问互斥锁。通过 1) 在互斥锁名称上使用“Global\”前缀和 2) 在创建互斥锁时指定适当的安全描述符来执行此操作。
    • @villintehaspam,您的断言是有效的,但我怀疑它们是否适用于 OP 的情况
    • 您可能是对的 - 我只是认为应该提供此信息,以便 OP 可以做出明智的决定是否关心此问题。
    • 感谢您的回答,我已经更改了代码以反映您的回答,您可以看看它是否有效?
    • @sigvardsen,好吧,忽略你的代码中有一些奇怪的......点的事实,它对我来说看起来是有效的:-)。只有你知道它是否真的有效。运行并测试它。如果出现问题,请提出另一个问题,说明到底出了什么问题,并且不要编辑此问题,使其成为另一个问题。
    【解决方案2】:

    您可以从位于 MSDN here 的“使用互斥对象”示例开始。为了在进程之间共享互斥体,您需要更改 CreateMutex 调用以获取名称。

    【讨论】:

    • 您需要确保 1) 其他进程(在其他用户的上下文中运行)获得相同的互斥锁,并且 2) 其他进程也可以访问互斥锁。通过 1) 在互斥锁名称上使用“Global\”前缀和 2) 在创建互斥锁时指定适当的安全描述符来执行此操作。
    • 如果他在以不同用户身份运行的进程之间共享映射的可写内存,那么他就有一个巨大的安全漏洞。依赖全局命名空间中的互斥锁是另一个巨大的安全漏洞,因为它可能很容易被占用。
    • 正确:互斥锁和文件映射应该使用相同的名称范围,并且可能两者都应该是会话本地的。
    【解决方案3】:

    您可能应该使用共享文件映射对象来创建共享内存,而不是使用链接器将部分标记为共享。一种相对简单的管理方法是将所有共享变量放入单个struct,然后将MapViewOfFile 的返回值转换为指向此结构的指针。

    当然,这个共享区不能有指针,但是进程之间可以交换索引信息(当然是指共享区的数组)。

    即使是链接器共享部分也不能保证在所有进程中加载​​到相同的地址。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-30
      • 2016-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多