多个std::线程和主程序执行出现问题
Trouble with multiple std::threads and main program execution
我几天来一直在努力想出一种机制来启动一些定时器,而不让它为主程序的执行计时。.join()
与.detach()
、wait_until()
等的组合
我有一个std::thread
的矢量,我想:
- 执行第一个位置
- 等它结束
- 执行下一个位置
- 等它结束
与此同时,我的应用程序的其余部分正在运行,用户点击东西,等等。我想到的一切似乎都是:
- 在计时器运行时阻止主程序运行
或
- 从主线程分离,但计时器同时运行,就像我希望的那样,在上一个线程完成后运行
我甚至发布了:C++11 std::threads并等待线程完成,但似乎都没有我能理解的解决方案。
我应该使用std::launch::async
吗?
编辑:我不知道为什么这对我来说如此难以理解。我的意思是,电子游戏总是这样。以《小塔》为例。你在地板上备货,从你开始备货到物品备货,每一项操作都会延迟,并触发HUD弹出,显示"地板现在备货了"。与此同时,整个游戏一直在运行,让你做其他事情。我一定很笨,因为我搞不清楚。
这段代码将在单独的线程中执行空任务的std::vector
。
typedef std::vector<std::function< void() >> task_list;
typedef std::chrono::high_resolution_clock::duration timing;
typedef std::vector< timing > timing_result;
timing_result do_tasks( task_list list ) {
timing_result retval;
for (auto&& task: list) {
std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();
task();
std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now();
retval.push_back( end-start );
}
return retval;
}
std::future<timing_result> execute_tasks_in_order_elsewhere( task_list list ) {
return std::async( std::launch::async, do_tasks, std::move(list) );
}
这应该在主线程之外串行运行每个任务,并返回包含计时结果的std::future
。
如果你想把计时结果分成小块(即在它们都准备好之前),你就必须做更多的工作。我会从std::packaged_task
开始,返回一个std::vector<std::future< timing >>
,然后从那里开始。
上面的代码是未经测试/未编译的,但不应该有任何根本的缺陷。
您会注意到,上面没有使用std::thread
。std::thread
是一个低级别的工具,您应该在它之上构建工具,而不是应该直接使用的工具(它非常脆弱,因为在销毁之前需要join
ed或detach
ed等)。
虽然std::async
没有什么可写的,但它非常适合快速而肮脏的多线程,在这种情况下,您希望执行串行任务并在"其他地方"执行。通过std::future
缺乏像样的信令使其不太通用(这也是您可能想要围绕std::thread
编写更高级别抽象的原因)。
这里有一个将运行一系列任务,其间的延迟最小:
#include <chrono>
#include <iostream>
#include <vector>
#include <functional>
#include <thread>
#include <future>
typedef std::chrono::high_resolution_clock::duration duration;
typedef std::chrono::high_resolution_clock::time_point time_point;
typedef std::vector<std::pair<duration, std::function< void() >>> delayed_task_list;
void do_delayed_tasks( delayed_task_list list ) {
time_point start = std::chrono::high_resolution_clock::now();
time_point last = start;
for (auto&& task: list) {
time_point next = last + task.first;
duration wait_for = next - std::chrono::high_resolution_clock::now();
std::this_thread::sleep_for( wait_for );
task.second();
last = next;
}
}
std::future<void> execute_delayed_tasks_in_order_elsewhere( delayed_task_list list ) {
return std::async( std::launch::async, do_delayed_tasks, std::move(list) );
}
int main() {
delayed_task_list meh;
meh.emplace_back( duration(), []{ std::cout << "hello worldn"; } );
std::future<void> f = execute_delayed_tasks_in_order_elsewhere( meh );
f.wait(); // wait for the task list to complete: you can instead store the `future`
}
这应该使助手CCD_ 17线程睡眠(至少与运行每个任务之前使用的持续时间一样长)。正如所写的那样,执行每项任务所花费的时间不计入延迟,因此,如果任务花费的时间比延迟时间长,则最终任务运行时几乎没有延迟。如果你愿意的话,改变它应该很容易。
您的麻烦是可以理解的,因为您需要的是一个事件循环,而C++还没有标准的定时器来阻止事件循环。您需要使用其他框架(如Qt、Boost.Asio(?)或不可移植的API(select()等)来编写事件循环。
- 如何解决 Ninja c++ 构建和执行问题
- 无法在问题解决方案中执行输出逻辑
- 在Linux上使用Clang / OLLVM交叉编译helloworld Windows可执行文件时的问题
- 在 C++ Consol 中的数组中执行用户命令时出现问题
- 如何通过使用 2 位或更多数字的 XOR 运算符来执行此操作C++问题
- 执行用 C++ 编写的.exe(使用 mingw 编译器)时出现问题
- Win7 C++ - 从以用户身份登录的服务启动可执行文件的问题
- MFC执行线程问题
- 代码问题将字符串转换为图表执行
- 将我的主输出库与测试可执行文件链接时出现问题
- 在C++中编译/执行 GDAL 时出现问题
- 函数返回本地变量,尽管变量不超出范围,没有编译器问题,并且代码执行
- R6010 执行后出错.if 语句在 for 循环中.[作业][中止已解决,发现新问题]
- 定义可以执行对象方法和独立函数的函数时出现问题
- 从Windows任务栏执行时ifstream问题
- 生成文件问题(体系结构x86_64的未定义符号:"_main",引用自:主可执行文件的隐式入口/启动)
- 这段代码出了什么问题?它在第二个 cin 可以执行之前终止
- 执行问题流
- 相同大小的2D和1D阵列之间的内存或执行问题
- c++并发、同步设计,避免多次执行问题