代码之家  ›  专栏  ›  技术社区  ›  theateist

如何使用性能计数器控制文件读取?

  •  2
  • theateist  · 技术社区  · 10 年前

    在驱动器G上执行了几个操作。我的程序应该从文件中读取数据。当磁盘使用率非常高(>90%)时,程序应该减慢读取速度,这样它不会干扰使用磁盘的其他进程。
    显然,我想,检查 Disk Time 呼叫后 get_data_from_file() 将导致计数器返回非常高的百分比,因为磁盘刚刚使用过。你可以在 image .

    关于如何正确检查 磁盘时间 ?

    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 回复  |  直到 10 年前
        1
  •  1
  •   Christophe    10 年前

    一个独立的监视线程可以帮助您更独立地测量磁盘使用情况。

    线程执行的函数如下所示:

    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++线程。当然,您可以使用特定于操作系统的线程编写类似的代码。