【发布时间】:2021-06-04 19:30:17
【问题描述】:
我被要求用两个异步线程来运行一个任务。一个应该移动车辆,另一个计算并绘制车辆覆盖的区域。代码的简化如下:
#include <iostream>
#include <vector>
#include <math.h>
#include <chrono>
using namespace std;
class Robot {
private:
bool moving;
vector<double> position;
double area_covered;
public:
Robot(const vector<double> &initial_position) {
moving = true;
position = initial_position;
area_covered = 0.0;
}
void get_area() {
static vector<double> previous_measure = this->position; // initialized with the first position the robot is in
while (this->moving) {
this->area_covered += sqrt(pow(this->position[0] - previous_measure[0]) + pow(this->position[1] - previous_measure[1]));
previous_measure = this->position; // save the new position for the next iteration
this_thread::sleep_for(chrono::milliseconds(600)); // sleep for 600 ms
}
}
void move_robot(const vector<vector<double> > &map) {
for (int i=1; i < map.size(); i++) {
this->position = map[i];
this_thread::sleep_for(chrono::milliseconds(500)); // sleep for 500 ms
}
this->moving = false;
}
};
int main () {
vector<vector<double> > path{
{0.0359, -0.013}, {0.0658, -0.0287}, {0.0736, -0.027}};
Robot r3(path[0]);
auto thread1 = std::async(&Robot::move_robot, &r3, path);
auto thread2 = std::async(&Robot::get_area, &r3);
thread1.join();
thread2.join();
return 0;
}
在方法get_area() 中,我多次使用this.position,这可能会有所不同,因为它在另一个线程中已更改。在执行get_area 时我不能阻塞另一个线程,但我必须避免在一个循环运行中使用不同的this.position。最简单的解决方案是创建另一个变量来保存this.position 的初始值,但是我想知道您是否有更好的 C++ 方法来做到这一点。它会是这样的:
void get_area() {
static vector<double> previous_measure = this->position; // initialized with the first position the robot is in
vector<double> auxiliar;
while (this->moving) {
auxiliar = this->position;
this->area_covered += sqrt(pow(auxiliar[0] - previous_measure[0]) + pow(auxiliar[1] - previous_measure[1]));
previous_measure = auxiliar; // save the new position for the next iteration
this_thread::sleep_for(chrono::milliseconds(600)); // sleep for 600 ms
}
}
此外,我需要在move_robot() 的方法/线程完成时通知get_area(),以便在下一次while 迭代中它也退出。现在我正在使用属性moving,但这样做我在每次迭代之前检查条件,而不是在最后。我可以在最后添加一个if 来检查它,但应该有一些更好的方法。
最后,我也非常感谢您对如何干净地将对象传递给两个异步线程并等待它们解决 C++ 方式的意见。
【问题讨论】:
-
在您的示例中没有理由使用多线程。
-
但是,您也可以将
positions 推送到队列并从另一个线程处理它。 -
我必须这样做。这是一个练习
标签: c++ multithreading