Как контролировать чтение из файла с помощью счетчиков производительности?

На диске G. выполняется несколько операций. Моя программа должна считывать данные из файла. Когда использование диска очень велико (>90%), программа должна замедлить чтение, чтобы не мешать другим процессам, использующим диск.
Очевидно, я полагаю, что проверка Disk Time после звонка get_data_from_file() приведет к тому, что счетчик вернет очень высокий процент, потому что диск только что использовался. Вы можете видеть это на изображении.

Любые предложения о том, как я могу правильно проверить Disk Time?

PDH_HQUERY query;
PDH_HCOUNTER counter;
PdhOpenQuery(NULL, 0, &query);
PdhAddCounterA(query, "\\LogicalDisk(G:)\\% Disk Time", 0, &counter);
PdhCollectQueryData(query);

auto getDiskTime = [&]()->double
{
    PDH_FMT_COUNTERVALUE fmtCounter;
    PdhCollectQueryData(query); 
    PdhGetFormattedCounterValue(counter, PDH_FMT_DOUBLE, 0, &fmtCounter);       

    return fmtCounter.doubleValue;
};

for(...)
{
   get_data_from_file();

   print_done_percentage();

   double diskUsage = getDiskTime();
   if(diskUsage >= 90)
   {            
       std::cout << "The disk usage is over << diskUsage << "%. I'll wait...                
       while(diskUsage >= 90)
       {
           diskUsage = getDiskTime();
           Sleep(500);
       }
   }
}

1 ответ

Решение

Отдельный поток мониторинга может помочь вам измерить использование диска с большей независимостью от записи.

Функция, выполняемая потоком, будет выглядеть так:

void diskmonitor(atomic<double>& du, const atomic<bool>& finished) {
    while (!finished) {         // stop looping as soon as main process has finished job
        du = getDiskTime();     // measure disk
        this_thread::sleep_for(chrono::milliseconds(500)); //wait
    }
}

Он связывается с основным потоком через атомарные (то есть, чтобы избежать гонки данных) переменные, передаваемые по ссылке.

Ваш цикл обработки будет выглядеть следующим образом:

atomic<bool> finished=false;            // tell diskmonitor that the processing is ongoing
atomic<double> diskusage=0;             // last disk usage read by diskmonitor
thread t(diskmonitor, ref(diskusage), ref(finished));   // launch monitor
for (int i = 0; i < 1000; i++)
{
    ...
    print_done_percentage();

    while (diskusage >= 90) {    // disk usage is filled in background
        std::cout << "The disk usage is over " << diskusage << ".I'll wait...\n";
        this_thread::sleep_for(chrono::milliseconds(500));
        }
    ...
}
finished = false;           // tell diskmonitor that i't's finished, so that it ends the loop
t.join();                   // wait until diskmonitor is finished. 

Этот пример со стандартными потоками C++. Конечно, вы можете написать что-то похожее с потоками, специфичными для ОС.

Другие вопросы по тегам