代码之家  ›  专栏  ›  技术社区  ›  Marc Bernier

LoadLibrary静态/全局和线程

  •  2
  • Marc Bernier  · 技术社区  · 16 年前

    假设我有一个具有以下静态/全局的DLL:

    ClassA Object;
    

    随着ClassA的实现,它还包含一个“常规”的ClassB,如果尚未构建ClassA,它将无法正常工作(这就是为什么我将ClassA设置为静态/全局的原因)。

    在Windows中,我相信dll加载程序将在调用ClassB的构造函数时加载该dll,对吗?在这一点上,将建造A级,然后建造B级。如果出现第二个线程并构造ClassB,则不会构造ClassA,因为它已经构造好了。

    现在,我的问题是——如果类B是由两个线程同时构造的呢?所以线程1将开始构造类A。在执行ClassB的构造函数之前,线程2是否会等到类A完全构造完成?

    换句话说,loadLibrary()是否使用CriticalSection来确保动态链接库的静态/全局的线程安全初始化?我的预感是“是的”,但我似乎找不到任何文件可以这样或那样说。

    3 回复  |  直到 16 年前
        1
  •  1
  •   Aaron Klotz    16 年前

    DllMain 由Windows加载器调用,同时保留一个称为“加载器锁”的内部关键部分,因此在 DLL_PROCESS_ATTACH 事件,在首次加载DLL时只发生一次。

        2
  •  1
  •   Luke    16 年前

    查看dllmain的文档;我相信它讨论了加载程序锁和初始化顺序。

        3
  •  0
  •   Foredecker    16 年前

    由于DLL由多个进程共享,因此不会像EXE那样初始化。您需要的是一个有效的单例对象,它是其他对象的一次性工厂。

    注意,我假设这里的“classa”和“classb”是指那些类的实例…

    例如,你可以有一个

    ClassA& GetTheClassAInstance();
    ClassB& GetTheClassBInstsance();
    

    第一次调用这些函数时,这些函数将确保类A和类B的全局实例被正确构造。