共享临时文件管理
Posted
技术标签:
【中文标题】共享临时文件管理【英文标题】:Shared temp file management 【发布时间】:2021-11-17 01:43:05 【问题描述】:我的应用程序启动了几个类似的进程。第一个创建了一个“全局”临时文件,它们都是红色/写入的。当最后一个进程被销毁时,这个文件需要被删除。 稍后可能会启动更多进程,并且应该重新创建此文件。 从各种示例中,我想出了一个管理器类,它使用自定义删除器(删除文件)创建 shared_ptr,并将 week_ptr 保存到这些对象中,以便能够根据请求分发它们。这可行,但我想知道是否有更好的方法,或者在我的代码中可以发现任何陷阱。
#include <iostream>
#include <memory>
#include <string>
#include <set>
bool ptr_less(std::weak_ptr<std::string> lhs, std::weak_ptr<std::string> rhs)
auto left = lhs.lock();
auto right= rhs.lock();
if (!left || !right)
return left < right;
return *left < *right;
struct Manager
std::shared_ptr<std::string> get(const std::string& filename)
auto result = resources.find( std::weak_ptr<std::string>(std::make_shared<std::string>(filename)) );
if (result != resources.end())
std::cout << "Exists: " << filename << std::endl;
if (auto sp = result->lock())
return sp;
resources.erase(result);
// Create new object to manage, auto deleting
std::shared_ptr<std::string> ptr(new std::string(filename),
[](std::string* str) std::cout << "remove: " << *str << std::endl; delete str; );
resources.emplace(std::weak_ptr<std::string>(ptr));
//cleanup null pointers
for (auto iter=resources.begin(); iter != resources.end(); )
if (!iter->lock())
iter = resources.erase(iter);
else
++iter;
return ptr;
//Keep track of files to share. std::set comparing values not pointers
std::set<std::weak_ptr<std::string>, decltype(ptr_less)*> resourcesptr_less;
;
static Manager custodian;
struct User
User(std::string name) : mName(std::move(name))
std::cout << "New user: " << mName << std::endl;
mGlob = custodian.get("global.json");
mSet = custodian.get("settings-" + mName + ".json");
mVal = custodian.get("values-" + mName + ".json");
~User()
std::cout << "~User(): " << mName << std::endl;
std::shared_ptr<std::string> mGlob;
std::shared_ptr<std::string> mSet;
std::shared_ptr<std::string> mVal;
std::string mName;
;
int main()
using namespace std;
User* ps3 nullptr ;
User ps1("ps1");
User ps2("ps2");
ps3 = new User("ps3");
delete ps3;
cout << "Resources size: " << custodian.resources.size() << endl;
User ps1("ps1");
cout << "Resources size: " << custodian.resources.size() << endl;
return 0;
Demo here
【问题讨论】:
看起来你只在resources
集合中保留弱指针。这不会使对象保持活动状态。
@RichardCritten resources
有意保留周指针,所以我不会让分配的对象超过它们的用处。如果result->lock()
失败,我打算通过
创建一个新对象。
进程与线程完全不同(顺便说一句,您在示例中没有使用任何线程),您甚至不能使用weak_ptr
跨进程边界。它如何工作?
这里提供的实现没有多大意义;如果经理没有给定的资源,它会实例化一个并返回它,同时持有weak_ptr
给它。如果有其他东西来请求相同的资源,它会将shared_ptr
交还给它,然后停止持有weak_ptr
,这意味着如果有对该资源的第三个请求,它将实例化另一个新的一个资源的对象,实际上可能已经在使用中。
这里的另一个问题是您必须进行整个临时堆分配才能进行查找。这可以通过使用透明比较器来避免。
【参考方案1】:
weak_ptr
可能是这里工作的错误工具。
考虑这一行:
auto result = resources.find( std::weak_ptr<std::string>(std::make_shared<std::string>(filename)) );
这里发生的是您在堆上创建filename
的副本并通过新创建的shared_ptr
对其进行管理。然后构造一个weak_ptr
,之后shared_ptr
超出范围,留下一个空的weak_ptr
。因此,您可能一开始就使用空的weak_ptr
。
如 cmets 中所述,shared_ptr
不是一种进程间通信技术。如果您想跨多个进程同步资源(您似乎想要这样做),您将需要适当的 IPC 机制。 C++ 标准库不提供这些,因此您必须为此目的查看其他库。
另请注意,您的 ptr_less
函数没有做有效的事情。在 C++ 中,你是 only allowed to compare certain related values 使用 operator <
。
【讨论】:
以上是关于共享临时文件管理的主要内容,如果未能解决你的问题,请参考以下文章