我有一个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()
函数并在超时期限后返回,如果它花费的时间太长了吗?
答案 0 :(得分:2)
使用system
的替代方法是特定于操作系统的API调用,例如statvfs。
但我同意它花了这么长时间才很奇怪。你可以重新创建吗?
答案 1 :(得分:1)
我已经看到'df'在挂载某些NFS fs但是客户端无法访问服务器时挂起。那么你有没有安装任何网络fs?
无论如何,正如其他人已经指出的那样,你应该使用statvfs()/ fstatvfs()而不是system()。如果挂起的fs不是你想要运行statvfs()的那个,这也可能有助于挂起。
答案 2 :(得分:0)
也许您可以尝试使用fstatvfs()/statvfs()
系统调用来获取可用磁盘空间量,并查看是否有任何区别。