我想知道当一个应用程序中的三个线程同时从DLL(几乎)调用静态方法时会发生什么。是否为每个线程加载了3个DLL实例,或者其他线程只有在第一个线程完成DLL静态方法后才能访问DLL(即)每个线程一旦轮到它就可以访问dll?< / p>
答案 0 :(得分:9)
是否加载了3个DLL实例,每个线程一个?
没有。每个进程一次加载 。 (这里有一些微妙的问题;如果你使用Load
和LoadFrom
,可能会加载相同的程序集两次。但这是一种罕见的情况,与线程无关。)
第一个线程完成DLL静态方法后,第二个和第三个线程是否只能访问DLL?
没有;静态方法不自动序列化。如果你需要这个方法来确保一次只有一个线程访问它,那么你将不得不编写代码来自己完成。
静态构造函数虽然表现得有点像。运行时将确保“赢得竞争”的线程将运行静态构造函数。其他线程将等待第一个线程完成cctor。有关详细信息,请阅读我最近的一系列文章。
答案 1 :(得分:3)
通常,代码会在中加载,即使对于非静态对象也是如此。
这是您必须担心的声明变量(统称为 state )中包含的信息,而不是代码。
答案 2 :(得分:2)
DLL只在内存中加载一次。
如果同一进程中有多个线程在DLL中进行调用或访问全局变量,则DLL必须通过使用关键部分保护对全局/共享数据的访问来保证线程安全。
如果来自多个进程的多个线程访问DLL,只要访问同一DLL的进程中没有多个线程,线程安全就不是问题。
操作系统巧妙地管理内存,因此最初它只以代码和数据部分的一个副本开始。数据部分页面以只读方式映射。当需要在其中一个进程中修改任何全局数据时,操作系统将获得分段错误并创建页面副本并将其映射为进程内存空间中的可写。这种方法称为写时复制。