我试图弄清楚操作系统如何处理加载相同 DLL/共享库的多个不相关进程。我关心的操作系统是 Linux 和 Windows,但在较小程度上也是 Mac。我认为我的问题的答案对于所有操作系统都是相同的。
我对显式链接特别感兴趣,但我也想知道隐式链接。我认为两者的答案也将相同。
这是迄今为止我发现的关于 Windows 的最佳解释:
“系统在所有加载的模块上维护每个进程的引用计数。调用 LoadLibrary 增加引用计数。调用 FreeLibrary 或 FreeLibraryAndExitThread 函数减少引用计数。当引用计数达到零或进程终止时,系统卸载模块(无论引用计数如何)。” - http://msdn.microsoft.com/en-us/library/windows/desktop/ms684175%28v=vs.85%29.aspx
但它留下了一些问题。
1.) 不相关的进程是否冗余地加载同一个 DLL(即 DLL 在内存中存在多次)而不是使用引用计数?(IE,进入每个进程自己的“地址空间”,因为我想我理解它)
如果在进程终止后立即卸载 DLL,这让我相信使用完全相同 DLL 的其他进程将冗余加载到内存中,否则不应允许系统忽略引用计数。
2.) 如果这是真的,那么当您在同一进程中多次加载它们时,引用计数 DLL 的意义何在?将同一个 DLL 两次加载到同一个进程中有什么意义?我能想到的唯一可行的原因是,如果一个 EXE 引用了两个 DLL,而其中一个 DLL 引用了另一个,那么对于同一个库,至少会有两个 LoadLibrar() 和两个 FreeLibrary() 调用。
我知道这似乎是我在这里回答我自己的问题,但我只是假设。我很想知道。
在GCC 4.6.1上,当我声明一个具有默认构造函数的我自己的类型的实例时,如果我实例化该类型的对象并用大括号(如Foo my_foo {};)初始化它,那个类中的POD成员如果没有声明其他构造函数,则只会进行零初始化.如果除了默认的构造函数之外没有其他构造函数,它们将像预期的那样零初始化.
但是,在GCC 4.7.3上,零初始化以任何一种方式发生,这是我预期的行为.
这有什么区别?这是编译器错误吗?这两个GCC版本都支持C++ 11标准的默认构造函数.
没有必要坚持旧的GCC版本,但我想了解这里发生了什么.
注意:我是默认主要的ctor,op =.并且复制ctor只是为了保持类型可用于可变参数函数(clang要求将类分类为POD,尽管gcc让我使用具有可变函数的类型,即使用户定义的主ctor.奖励积分,如果你能告诉我我为什么.)
这是一个示例程序,包括底部的一些输出(来自使用两个GCC版本编译的二进制文件):
#include <cstdio>
// pod and pod_wctor are identical except that pod_wctor defines another ctor
struct pod {
pod( void ) = default;
pod( const pod& other ) = default;
pod& operator=( const pod& other ) = default;
int x,y,z;
};
struct pod_wctor {
pod_wctor( void ) = default;
pod_wctor( const int setx, const int sety, const int setz ) : x(setx), y(sety), z(setz) { }
pod_wctor( const pod_wctor& …Run Code Online (Sandbox Code Playgroud) 假设我在一些不同类类型的其他对象中有一个对象和10个指针.如果删除对象,则必须将这些指针设置为null.通常我会将对象的类与具有指针的类互连,以便它可以通知它们它被删除,并且可以将它们的指针设置为null.但是这也有负担,当类被删除时类也必须通知对象,因为对象也需要指向它们的指针.这样,当对象破坏并尝试通知其他对象时,该对象不会将取消引用称为悬空指针.
我不喜欢这个混乱的废话网,我正在寻找一个更好的方法.
请注意,自动指针和共享指针不是我正在寻找的 - 自动指针在它们销毁时删除它们的对象,并且当没有更多的共享指针指向它时,共享指针也会这样做.我正在寻找的是一个灵活的方法,用于在对象析构时将对象的所有指针设置为null.
更新:我在这里修改了代码,以便您可以直接插入并尝试编译.
Clang 3.4.1(LLVM 3.4)抱怨我的类在可变参数函数中使用时不是POD类型(据我能说的最多).G ++编译没有问题.
即使按照C++ 03的标准,这个类也是POD:
而C++ 11对"POD"的规则是放松的,那么这里发生了什么?
关于代码:这是矢量的模板类(如矢量图形中所示),可变参数函数仅用于使用一些任意数据填充数组.
我的类头文件:
template<typename TYPE>
class Vec3t;
typedef Vec3t<float> Vec3f;
template<typename TYPE>
class Vec3t {
public:
Vec3t<TYPE>( void ){}
Vec3t<TYPE>( const TYPE nx, const TYPE ny, const TYPE nz ){}
Vec3t<TYPE> operator-(void) const{}
Vec3t<TYPE> operator*( const Vec3t<TYPE> &other ) const{}
Vec3t<TYPE> operator*( const TYPE val ) const{}
Vec3t<TYPE>& operator*=( const Vec3t<TYPE> &other ){}
Vec3t<TYPE>& operator*=( const TYPE val ){}
Vec3t<TYPE> operator+( const Vec3t<TYPE> &other ) const{}
Vec3t<TYPE> operator+( …Run Code Online (Sandbox Code Playgroud)