На диске 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);
}
}
}
Отдельный поток мониторинга может помочь вам измерить использование диска с большей независимостью от записи.
Функция, выполняемая потоком, будет выглядеть так:
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 ++. Конечно, вы можете написать что-то похожее с потоками, специфичными для ОС.