There are several operations being done on drive G. My program should read data from file. When the disk usage is very high(>90%) the program should slow down the reading so it won't interfere with other processes that uses the disk.
Obviously, I guess, that checking the Disk Time
after calling get_data_from_file()
will cause the counter to return very high percentage because the disk was just used. You can see that on the image.
Any suggestions on how I can check correctly the 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);
}
}
}
A distinct monitoring thread could help you measure disk usage with more independence from the writing.
The function executed by the thread would look like this:
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
}
}
It communicates with the main thread through atomic (i.e. to avoid data races) variables passed by reference.
Your processing loop would look as follows:
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.
This example is with standard C++ threads. Of course you could code something similar with OS specific threads.