c++ - 这对于等待使用std::future wait()返回的函数的CPU使用率更好,还是在循环中检查标志 sleep 一段时间?

标签 c++ multithreading wait

问题1:哪个会占用较少的CPU使用率,将来的wait()或while循环中的check标志?

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():
if(f.vaild())
   f.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会在错误的时间不必要地唤醒线程。结果准备就绪和服务线程注意到的平均延迟是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_thread::sleep_for(1ms):
         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        

即在此特定测试中,sleep_for消耗的CPU周期大约是其6倍。

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

关于c++ - 这对于等待使用std::future wait()返回的函数的CPU使用率更好,还是在循环中检查标志 sleep 一段时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59560318/

相关文章:

c++ - QT线程中的Lua脚本

java - 我的代码线程不安全吗?

c# - CPU + 时间密集型方法的 Thread.Abort 替代方案

安卓线程/回调

javascript setAttribute 函数

c++ - 如何通过首先检查它们是否用 New() 初始化来删除 vtk 对象?

c++ - fscanf 卡在第一行

c - fork 多个进程并让父进程等待所有进程(在 C 中)

user-interface - Blackberry - 带动画的加载/等待屏幕

c++ - 将 char * 转换为 QString 并删除零