C++ 等待std::future wait()返回的函数或在循环中检查标志sleep一段时间,哪个CPU使用率更好?

C++ 等待std::future wait()返回的函数或在循环中检查标志sleep一段时间,哪个CPU使用率更好?,c++,multithreading,wait,C++,Multithreading,Wait,Q1:while循环中的future wait()或check标志占用更少的CPU使用率 std::atomic_bool isRunning{false}; void foo(){ isRunning.store(true); doSomethingTimeConsuming(); isRunning.store(false); } std::future f = std::async(std::launch::async, foo); 使用std::future

Q1:while循环中的future wait()或check标志占用更少的CPU使用率

std::atomic_bool isRunning{false};

void foo(){
    isRunning.store(true);
    doSomethingTimeConsuming();
    isRunning.store(false);
}

std::future f = std::async(std::launch::async, foo);
使用std::future wait():

检查while循环中的标志:

if(f.valid){
    while(isRunning.load())
       std::this_thread::sleep_for(1ms);
}
问题2:结论是否也适用于std::thread.join()或std::condition_variable.wait()


提前谢谢

std::this_thread::sleep_for
总是在错误的时间不必要地唤醒线程。结果准备就绪且服务员线程注意到它的平均延迟是超时的
睡眠时间的一半

std::future::wait
效率更高,因为它在内核中阻塞,直到结果准备就绪,而不必执行不必要的多个系统调用,这与
std::this_thread::sleep_for
不同

如果您使用运行这两个版本

void doSomethingTimeConsuming() {
    std::this_thread::sleep_for(1s);
}
perf stat
下,std::future::wait
的结果如下:

          1.803578      task-clock (msec)         #    0.002 CPUs utilized          
                 2      context-switches          #    0.001 M/sec                  
                 0      cpu-migrations            #    0.000 K/sec                  
               116      page-faults               #    0.064 M/sec                  
         6,356,215      cycles                    #    3.524 GHz                    
         4,511,076      instructions              #    0.71  insn per cycle         
           835,604      branches                  #  463.304 M/sec                  
            22,313      branch-misses             #    2.67% of all branches        
而对于
std::this\u thread::sleep\u(1ms)

也就是说,在这个特定的测试中,的
sleep\u消耗的CPU周期大约是原来的6倍



请注意,
isRunning.load()
isRunning.store(true)
之间存在竞争条件。修复方法是初始化
isRunning{true}

任何等待操作都比在循环中短暂休眠需要更少的CPU。在等待期间,线程释放CPU时间片,因此它可用于其他需要它的线程,而循环要求线程获取时间片(在退出睡眠后)
wait
可能会阻塞同步原语,例如条件变量。高效。比紧密循环中的轮询更有效。而且平均而言,最终睡眠时间将是所需时间的两倍。等待不会太久。
          1.803578      task-clock (msec)         #    0.002 CPUs utilized          
                 2      context-switches          #    0.001 M/sec                  
                 0      cpu-migrations            #    0.000 K/sec                  
               116      page-faults               #    0.064 M/sec                  
         6,356,215      cycles                    #    3.524 GHz                    
         4,511,076      instructions              #    0.71  insn per cycle         
           835,604      branches                  #  463.304 M/sec                  
            22,313      branch-misses             #    2.67% of all branches        
         11.715249      task-clock (msec)         #    0.012 CPUs utilized          
               901      context-switches          #    0.077 M/sec                  
                 6      cpu-migrations            #    0.512 K/sec                  
               118      page-faults               #    0.010 M/sec                  
        40,177,222      cycles                    #    3.429 GHz                      
        25,401,055      instructions              #    0.63  insn per cycle
         2,286,806      branches                  #  195.199 M/sec  
           156,400      branch-misses             #    6.84% of all branches