std :: thread没有按预期立即启动(c ++ 11)

时间:2018-05-02 06:22:14

标签: c++ multithreading

我的main.cpp

中有以下代码
std::thread t1(&AgentsSourcesManager::Run, &sim.GetAgentSrcManager());
doSomething(); // in the main Thread
t1.join();

我期待t1立即开始并沿主线程开始。 然而,这种情况并非如此。我测量我的程序的执行时间,重复这100次并制作一些图。

见下图中的峰值。

enter image description here

现在,如果我在创建t1

后稍等一下
std::this_thread::sleep_for(std::chrono::milliseconds(100));

我得到了更好的结果。见下图。

enter image description here

(仍然有一个高峰,但很好......)

显然我的问题是:

  • 为何达到顶峰?
  • 为什么我没有直线?

修改

好的,从我现在所理解的评论来看,可能会有一些调度程序的魔法。

这是一个工作示例

#include <thread>
#include <chrono>
#include <iostream>
#include <pthread.h>
#include <functional>
int main() {
     float x = 0;     float y = 0;
     std::chrono::time_point<std::chrono::system_clock> start, stop;

    start= std::chrono::system_clock::now();
    auto Thread = std::thread([](){std::cout<<"Excuting  thread"<<std::endl;});
    stop = std::chrono::system_clock::now();

    for(int i = 0 ; i<10000 ; i++)
         y += x*x*x*x*x;

    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    Thread.join();

     std::chrono::duration<double> elapsed_time = stop - start;
     std::cout << "Taken time: " << std::to_string(elapsed_time.count()) << "  "<< std::endl;
    return 0;
}

编译:

g++-7 -lpthread  threads.cpp -o out2.out

对于分析,我使用此代码

import subprocess
import matplotlib.pyplot as plt
import numpy as np

RUNS = 1000
factor = 1000
times = []
for i in range(RUNS):
    p = subprocess.run(["./out2.out"], stdout=subprocess.PIPE)
    line = p.stdout
    times.append(float(line.split()[-1]))
    print(i, RUNS)


times = np.array(times)  * factor
plt.plot(times, "-")
plt.ylabel("time * %d" % factor)
plt.xlabel("#runs")
plt.title("mean %.3f (+- %.3f), min = %.3f, max = %.3f" %
          (np.mean(times), np.std(times), np.min(times), np.max(times)))

plt.savefig("log2.png")

结果

enter image description here

我想我最好问:我怎样才能减少这种延迟并告诉我的操作系统,这个线程对我来说真的很重要,应该有更高的优先级?

1 个答案:

答案 0 :(得分:3)

你不是在衡量你认为你在这里测量的东西:

start= std::chrono::system_clock::now();
auto Thread = std::thread([](){std::cout<<"Excuting  thread"<<std::endl;});
stop = std::chrono::system_clock::now();

stop时间戳只给出了main生成该线程需要多长时间的上限,它实际上告诉你 nothing 关于该线程何时开始执行任何实际工作(为此你需要在线程中加上时间戳)。

此外,system_clock并非大多数平台上进行此类测量的最佳时钟,默认情况下您应使用steady_clock,如果那个没有给您high_resolution_clock,请使用std::thread足够精确(但请注意,你必须自己处理那个时钟的非单调性质,这很容易让你获得精确度)。

正如评论中已经提到的,产生一个新线程(因此也构建一个新的std::condition_variable)是一个非常复杂和耗时的操作。如果你需要很高的响应能力,那么你想要做的就是在你的程序启动过程中产生几个线程,然后让它们等待#fullpage { height:100vh; width:100%; } .vertical-center{ display: flex; justify-content: center; align-items: center; } .circle{ background-color: #ff9933; /* margin-top:-300px; */ z-index: 300; position: absolute; height: 480px; width:480px; border-radius: 50%; /* top:15%; */ } .process-container { position: relative; } .circle-text { text-align: center; color: white; font-family: 'Muli', sans-serif; font-weight: 200; },一旦它们的工作变得可用就会发出信号。这样你可以确定在一个空闲的系统上,一个线程将开始处理分配给他的工作非常快(由于操作系统如何调度线程,大多数系统都不能立即)但延迟应该在一毫秒之内。