【发布时间】:2011-06-17 07:55:39
【问题描述】:
我有一个 C++ 程序,可以长时间连续记录大量数据到磁盘。因此,我有一个线程来监视可用的磁盘空间,一旦达到一定百分比就会做一些事情。
这是在双四核 x64 CentOS 系统上进行的,并且记录发生在直接连接的 SATA 磁盘上,这些磁盘仅用于使用 ext3 文件系统进行记录。我通过使用system() 发出“df”命令并读取结果来监控磁盘使用情况。
昨晚运行它时,我在日志文件中注意到它花了 整整 39 分钟来运行命令来查找磁盘使用情况。
处理超时的代码是这样的:
int DiskSpaceMonitor::handle_timeout(const ACE_Time_Value& time_, const void* pFunc_)
{
LOG4CXX_TRACE(m_logger, "DiskSpaceMonitor timer fired");
ACE_UINT8 usagePercent = m_diskChecker.getDiskSpaceUsagePercentage(m_monitoredDisk);
m_fileRecorder->notifyDiskUsage(usagePercent);
return 0;
}
调用执行“df”的函数:
ACE_UINT8 DiskSpaceChecker::getDiskSpaceUsagePercentage(std::string diskMountPoint)
{
std::stringstream usageCommand;
usageCommand << "df -PH " << diskMountPoint << " | grep -v \"^Filesystem\" | awk '{print $5}' | cut -d'%' -f1 > " << m_mountSpaceFile;
system(usageCommand.str().c_str());
std::ifstream inFile(m_mountSpaceFile.c_str(), std::ios::in);
if (!inFile)
{
return 0;
}
std::string usageStr;
inFile >> usageStr;
int usage = atoi(usageStr.c_str());
inFile.close();
std::stringstream rmCmd;
rmCmd << "rm " << m_mountSpaceFile;
system(rmCmd.str().c_str());
LOG4CXX_DEBUG(m_logger, "Disk usage for disk: " << diskMountPoint << " = " << usage << "%");
return usage;
}
因此,handle_timeout() 中的跟踪记录语句和getDiskSpaceUsagePercentage() 中的调试跟踪语句之间花费了 39 分钟。但是延迟确实在inFile >> usageStr; 之前出现(因为我可以看到读取百分比高于预期 - 它应该上升 1% 或更少,但它跃升超过 16%)。
为什么运行命令和读取命令的处理要花费如此大量的时间?
现在我承认磁盘在被写入时确实会受到一些冲击,但只有一个程序在写入它们,而且它只写入一个数据文件和一个索引文件。所以我不明白这需要这么长时间。
作为替代方案,是否有一种简单的方法可以调用 system() 函数并在超时时间过长时让它返回?
【问题讨论】:
-
我不确定,但是
getrusage可以选择吗? -
在这个缓慢的响应过程中知道 iowait 状态是什么样子会很有趣。
标签: c++ performance file-io system