Ten*_*gis 6 c++ multithreading
我的代码中包含以下代码 main.cpp
std::thread t1(&AgentsSourcesManager::Run, &sim.GetAgentSrcManager());
doSomething(); // in the main Thread
t1.join();
Run Code Online (Sandbox Code Playgroud)
我期待t1立即开始并沿主线开始.然而,这种情况并非如此.我测量我的程序的执行时间,重复这100次并制作一些图.
请参见下图中的峰值.
现在如果我在创建之后稍等一下 t1
std::this_thread::sleep_for(std::chrono::milliseconds(100));
Run Code Online (Sandbox Code Playgroud)
我得到了更好的结果.见下图.
(仍然有一个高峰,但很好..)
显然我的问题是:
好吧,根据我现在所理解的评论,可能会有一些调度程序魔术正在进行中.
#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;
}
Run Code Online (Sandbox Code Playgroud)
g++-7 -lpthread threads.cpp -o out2.out
Run Code Online (Sandbox Code Playgroud)
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")
Run Code Online (Sandbox Code Playgroud)
我想我最好问:我怎样才能减少这种延迟并告诉我的操作系统,这个线程对我来说真的很重要,应该有更高的优先级?
你没有测量你认为你在这里测量的东西:
start= std::chrono::system_clock::now();
auto Thread = std::thread([](){std::cout<<"Excuting thread"<<std::endl;});
stop = std::chrono::system_clock::now();
Run Code Online (Sandbox Code Playgroud)
时间戳仅提供了生成该线程stop所需时间的上限,并且实际上并没有告诉您该线程何时开始执行任何实际工作(为此,您需要在线程内获取时间戳)。main
另外,system_clock这并不是大多数平台上进行此类测量的最佳时钟,您应该steady_clock默认使用,high_resolution_clock如果该时钟不能为您提供足够的精度,则应采用该时钟(但请注意,您将必须处理该时钟的非单调性质)那么你自己,这很容易搞乱你获得的精度)。
正如评论中已经提到的,生成一个新线程(从而也构造一个新的std::thread)是一个非常复杂且耗时的操作。如果您需要高响应能力,您要做的就是在程序启动期间生成几个线程,然后让它们等待,std::condition_variable一旦它们的工作可用,就会收到信号。这样,您可以确保在空闲的系统上,线程将很快开始处理分配给他的工作(由于操作系统调度线程的方式,在大多数系统上立即不可能,但延迟应该远远低于一毫秒)。