如何向线程发出正确结束的信号

  • 本文关键字:结束 信号 线程 c++
  • 更新时间 :
  • 英文 :


所以我正在做一个学校项目来模拟一场实时的汽车大战。代码如下:

void attack(Fighter& f1, Fighter& f2)
{
while (!f1.is_down()&&!f2.is_down())
{
this_thread::sleep_for(chrono::seconds(f1.get_spd())/10);
cout << f1.get_name() << " dealt " << f2.get_dmg(f1) << " damage" << endl;
}
if (f2.is_down()) cout << 't' << f2.get_name() << "is defeated" << endl;
}
void Fight::fight_start()
{
thread f1_attack(attack, f1, f2);
thread f2_attack(attack, f2, f1);
f1_attack.join();
f2_attack.join();
}

战斗本应在一方被击败时结束,但他们一直战斗到双方都倒下。如何阻止被击落的战斗机继续战斗?

编辑:我修复了它。

在C++中,如果一个线程修改数据,则必须以某种方式同步任何读取器。如果没有,则程序的行为不是由C++标准定义的,这是不好的。

我认为你在这里使用线程的方式在某些方面是不好的。

  1. 您的访问权限是UB,或者您使用的是按对象锁定。第一种情况意味着你的计划资金严重不足;第二种是不组合的多线程编程。(不组成意味着两段"正确"的代码,当连接时,可能会对问题产生错误。(

  2. 你花了一根昂贵的线作为一个荣耀的计时器。

  3. 您正在从多个线程执行非同步io。

  4. 即使您对每个方法都进行了互斥锁,您的线程代码也会被破坏。例如,死亡的战士可以攻击。

我在这里要做的是:

制作一个单独的调度程序。它有一个要做的任务的排序deque或multimap(关键是时间(。当你添加任务时,你会说你希望它们何时弹出。当你等待任务时,它会让你等到有一个任务的时间到来。

可能是这样的:

struct scheduler{
using clock=std::chrono::steady_clock;
using time_point=clock::time_point;
using task=std::function<void(time_point)>;
task pop();
void push(time_point, task);
void push_now(task){ push(clock::now(), std::move(task)); }
private:
mutable std::mutex m;
std::condition_variable cv;
std::multimap<clock::time_point, task> queue;
};

你的战士;线程";不再是线程。

scheduler fight;
fight.push_now([&](auto when){
round(fight, when, f1, f2);
});
fight.push_now([&](auto when){
round(fight, when, f2, f1);
});
while(auto f=fight.pop()){
f();
}

圆形可能是:

void round(scheduler& fight, scheduler::time_point when, fighter& attacker, fighter& defender){
if (!attacker.is_down()&&!defender.is_down()){
std::cout<<attacker.name()<< " hits "<< defender.name() << " for " << attacker.do_dmg(defender) <<"n";
}
if (defender.is_down()){
std::cout<<defender.name()<<" defeated.";
}
if (attacker.is_down()){
std::cout<<attacker.name()<<" defeated.";
}
if Iattacker.is_down()||defender.is_down())
fight.push_now({});// end
else
fight.push(when+chrono::seconds(f1.get_spd()/10.), [&](auto when){round(fight, when, attacker, defender);});
}

如果需要,可以在线程中运行调度程序。

可能有打字错误。你必须重新研究如何使用条件变量来睡眠,直到超时或收到新消息。

最新更新