Очень медленно выполняется системная команда - PullRequest
1 голос
/ 17 июня 2011

У меня есть программа на C ++, которая долгое время непрерывно записывает много данных на диск.Таким образом, у меня есть поток, который отслеживает доступное дисковое пространство, и, как только он достигает определенного процента, делает некоторые вещи.

Это двухъядерная система x64 CentOS, и запись происходит на напрямую подключенных дисках SATA, которые используются исключительно для записи с файловой системой ext3.Я наблюдаю за использованием диска, выполнив команду "df", используя system() и прочитав результат.

Во время его запуска вчера вечером я заметил в файлах журнала, что это заняло целых 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() и вернуть ее после истечения времени ожидания, если оно занимает слишком много времени?

Ответы [ 3 ]

2 голосов
/ 17 июня 2011

Альтернативой использованию system является специфический для ОС вызов API, например statvfs .

Но я согласен, это странно, что так долго. Вы можете воссоздать это?

1 голос
/ 17 июня 2011

Я видел зависание df при монтировании некоторых файловых систем NFS, но клиент не может получить доступ к серверу.Так у вас есть какая-нибудь сеть, смонтированная с помощью fs?

В любом случае, как уже отмечали другие, вы должны использовать statvfs () / fstatvfs () вместо system ().Это также может помочь с зависанием, если зависший fs не тот, на котором вы пытаетесь запустить statvfs ().

0 голосов
/ 17 июня 2011

Возможно, вы могли бы попробовать использовать системные вызовы fstatvfs()/statvfs(), чтобы получить вместо этого объем свободного дискового пространства, и посмотреть, имеет ли это какое-то значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...