2

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);
       }
   }
}
theateist
  • 13,879
  • 17
  • 69
  • 109

1 Answers1

1

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.

Christophe
  • 68,716
  • 7
  • 72
  • 138
  • I ended with exactly same solution:) I logged in to delete my post but you've already answered:) But, I still find your answer helpful since I used C `CreateThread` and I like your c++ thread usage. – theateist Sep 04 '14 at 02:34