这是一个很好的小问题/练习:
我正在开发一个Qt库,需要跟踪谁在使用特定的共享资源。如果我只是在一个应用程序中考虑这个,我会使用类似于QMap<resourceName, QMap<userName,QList<resourceInstance*> > >
的注册表,它将实例列表映射到命名用户使用的命名资源。实例可能只是实例构造函数中的this
指针,它会向注册表添加一个新条目(并且在析构函数中也是如此)。
但是,这里的users
是应用程序,并且可以有任意数量的(理论上)单个资源的任意数量的实例。
这意味着:
1-我的注册表必须采用某种形式的共享内存
2-共享内存不能轻易成为文件(或存储在共享资源中的属性),因为在崩溃或其他不清洁的情况下,它很容易被破坏
3-当操作系统将并发应用程序映射到同一内存空间时,使用注册表中的实例地址可能会导致别名。
这超出了我已经涉及的共享内存(即仅在线程之间,而不涉及可以增长和缩小的动态结构)。
解决这个问题的最佳方法是什么?在早期的实现(固定大小的对象)中,我重载了new运算符以在共享内存中分配,但我不认为这是一种可行的方法 - 而不是在我希望使用Qt / STL类时。 Qt自己的SharedMemory类似乎不适合动态对象,因为我没有看到调整现有共享段的方法......
是否有可以使用的Cocoa IPC框架,从10.6开始存在?
如果OS X可以打开已取消链接的文件(但在至少1个[其他]应用程序中仍处于打开状态且因此未被擦除),则可以使用基于文件的替代方法。这样,不洁的存在不能破坏注册表。假设操作系统可以这样做,我认为“技巧”是在RW模式下打开文件,在读取之前锁定它,在(重新)写入之后将其解锁,在对内存中注册表进行任何修改之前读取其内容然后立即重写它?
扰乱:Qt库是KDE的kwallet框架,共享资源是存储在OS X keychain文件中的KDE钱包。基本的想法是能够重新实现kwallet功能,以便在不再使用时关闭钱包(钥匙串)(当前实现需要守护程序进程,使用DBus并且在[尚未]上运行良好OS X)。答案 0 :(得分:0)
由于您使用Qt,我真的不喜欢特定于平台的黑客攻击。您只需使用命名的本地套接字即可。它们适用于Qt工作的任何地方。
然后,您可以决定数据是由库的每个实例以分布式方式存储(可能与使用它的应用程序相关联),还是由中央单实例服务决定。