提问人:lstipakov 提问时间:8/11/2016 更新时间:11/20/2017 访问量:5197
正确读取 /proc/pid/status 的方式
Correct way of reading /proc/pid/status
问:
我是这样读的:/proc/<pid>/status
std::ifstream file(filename);
std::string line;
int numberOfLinesToRead = 4;
int linesRead = 0;
while (std::getline(file, line)) {
// do stuff
if (numberOfLinesToRead == ++linesRead) {
break;
}
}
我注意到在极少数情况下会挂起。std::getline
- 为什么会这样?我的印象是 proc 文件系统应该处于某种一致的状态,并且不应该出现缺少换行符的情况。我的假设是,当发生 EOF/错误时返回。
getline
false
- 推荐的、安全的阅读方式是什么?
/proc/<pid>/status
答:
0赞
Matthew Fisher
8/11/2016
#1
也许更确定的路径是将 fread 使用到一个大缓冲区中。状态文件很小,因此请分配一个本地缓冲区并读取整个文件。
示例:查看最简单解决方案的第二个答案
这可能仍然在 fopen 或 fread 上失败,但应该返回一个合理的错误。
-2赞
Alexey Kamenskiy
8/13/2016
#2
/proc 是一个虚拟文件系统。这意味着从其中的“文件”读取与从普通文件系统读取不同。
如果进程退出,则从 /proc 中删除有关它的信息比实际文件系统快得多(这里涉及脏缓存刷新延迟)。
请记住这一点,想象一下,在您阅读尚未缓冲的下一行之前,该进程会退出。
解决方案是考虑文件丢失,因为您可能不需要有关不再存在的进程的信息,或者缓冲整个文件,然后只解析它。
编辑:挂起进程显然应该与这是虚拟文件系统这一事实有关。它的行为方式与实际文件系统不完全相同。由于这是特定的 fs 类型,因此问题可能出在 fs 驱动程序中。您提供的代码对于正常文件读取来说看起来不错。
评论
0赞
osgx
3/11/2017
亚历克斯,在问题的示例中,进行了哪些系统调用以从 proc 读取文件?那里有多个系统调用吗?对整个文件(全有或全无)进行一次性足够大的读取,然后从用户缓冲区进行解析会更安全。
评论
std::getline
不返回布尔值,它返回可以在布尔表达式中使用的流。/proc/<some pid other than your own>/
OS
/proc
strace