gpt4 book ai didi

c++ - 段错误和 RAII

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:14:50 25 4
gpt4 key购买 nike

这更像是一种哲学类型的问题。

C++ 中,我们有漂亮 Shiny 的习惯用法 - RAII。但我常常认为它是不完整的。它与我的应用程序可以被 SIGSEGV 杀死的事实不太吻合。

我知道,我知道,你说这样的程序格式错误。但令人遗憾的是,在 POSIX(特别是 Linux)上,您可以分配超出物理内存限制并在执行过程中遇到 SIGSEGV,使用正确分配的内存。

你可能会说:“应用程序死了,你为什么要关心那些没有被调用的可怜的析构函数?”。不幸的是,有些资源在应用程序终止时不会自动释放,例如文件系统实体。

我现在厌倦了设计 hack,破坏良好的应用程序设计来应对这种情况。所以,我所要求的是为此类问题提供一个漂亮、优雅的解决方案。

编辑:

看来我错了,在 Linux 上应用程序被内核寻呼机杀死。在这种情况下,问题仍然相同,但应用程序死亡的原因不同。

代码片段:

struct UnlinkGuard
{
UnlinkGuard(const std::string path_to_file)
: _path_to_file(path_to_file)
{ }

~UnlinkGuard() {
unlink();
}

bool unlink() {
if (_path_to_file.empty())
return true;

if (::unlink(_path_to_file.c_str())) {
/// Probably some logging.
return false;
}

disengage();
return true;
}

void disengage() {
_path_to_file.clear();
}

private:
std::string _path_to_file;
};

void foo()
{
/// Pick path to temp file.
std::string path_to_temp_file = "...";

/// Create file.
/// ...

/// Set up unlink guard.
UnlinkGuard unlink_guard(path_to_temp_file);

/// Call some potentially unsafe library function that can cause process to be killed either:
/// * by a SIGSEGV
/// * by out of memory
/// ...

/// Work done, file content is appropriate.
/// Rename tmp file.
/// ...

/// Disengage unlink guard.
unlink_guard.disengage();
}

成功后我使用文件。失败时我希望这个文件丢失。

如果 POSIX 支持 link() - 通过文件描述符连接以前未链接的文件,这可以实现,但没有这样的功能:(。

最佳答案

So, what I am asking is for a nice, elegant solution to this kind of problems.

不存在,无论是 C++ 还是其他语言。您在这里面临的是一个基本的物理现实,而不是设计决策:当用户拔下插头时会发生什么?没有任何编程解决方案可以防止这种情况(好吧,有重启时恢复)。

可以做的是捕获 POSIX 信号,有时您甚至可以处理它们——但它很不稳定,而且有很多警告,another discussion on Stack Overflow details

大多数资源不应在段错误后被清除。如果您仍然想这样做,只需将这些资源(或者更确切地说,用于清理的处理程序)收集到一个全局数组 trap SIGSEGV 中,遍历处理程序中的清理例程数组(希望相关内存仍然完好无损),然后执行清理。

更具体地说,对于临时文件,它有助于在系统的临时文件夹之一中创建它们。据了解,这些并不总是由各自的应用程序清理,而是系统或用户会定期执行清理。

关于c++ - 段错误和 RAII,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25781360/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com