如何在单线程系统上停止阻塞任务?

huangapple go评论65阅读模式
英文:

How do I stop a blocking task on single threaded systems?

问题

我正在为单线程微控制器编写代码,遇到了一个问题。如何阻止 Foo bar 执行?
在我的控制器上不可能使用 <thread><future>。命令 bar.stop() 不是确定性的。它应该被用作随机用户输入。

class Foo {
public:
  void start() {
    while (true) {
      if (m_stopped) { return; }
      // 做一些操作...
    }
  };

  void stop() {
    m_stopped = true;
  };

private:
  bool m_stopped = false;
};

int main() {
  Foo bar;

  bar.start();
  bar.stop();

  return 0;
}

谢谢您的帮助!

英文:

I'm coding for a single threaded microcontroller and bumped into an issue. How do I stop Foo bar from executing?
The use of <thread> and <future> is not possible on my controller. The command bar.stop() is not deterministic. It shall be used as a random user input.

class Foo{
  public:
    void start() {
      while(true) {
        if(m_stopped) { return; }
        //do something...
      }
    };

    void stop() {
      m_stopped = true;
    };

  private:
    bool m_stopped = false;
};

int main() {
  Foo bar;

  bar.start();
  bar.stop();

  return 0;
}

Thanks for your help!

答案1

得分: 3

如果系统是单线程的,没有抢占式多任务处理,那么从外部是无法做任何事情的。系统本质上只能做一件事情:当前正在执行的那件事情。甚至无法考虑任务是否运行时间过长,因为所有用于“考虑”事情的元素都被任务占用。

如果没有操作系统级别的抢占或某种中断机制,就无法从函数外部使其停止。因此,必须编写Foo::start函数,使其根据某些标准来停止自身或者提供一个定期调用的函数指针来告诉它是否应该停止。

using StopFunc = bool(*)(void*);

...

void start(StopFunc stop_func, void* param) {
  while(true) {
    if(stop_func(param)) { return; }
    //做一些事情...
  }
};
英文:

If the system is single-threaded, and there is no preemptive multitasking, then there's nothing you can do from the outside. The system, by its nature, can do exactly and only one thing: the thing its currently doing. There's no way to even consider whether the task has been running for too long because all elements devoted to "considering" stuff are being used by the task in question.

Without OS-level preemption or some kind of interrupt, there's no way to cause something to stop from the outside of that function. That function must therefore be written to stop itself based on some criteria.

So you have to write Foo::start in such a way that it either has the stopping criteria baked in or is given a function pointer to call periodically to tell it if it should stop.

using StopFunc = bool(*)(void*);

...

    void start(StopFunc stop_func, void* param) {
      while(true) {
        if(stop_func(param)) { return; }
        //do something...
      }
    };

答案2

得分: 2

Frankly, you are making this more complicated than necessary by trying to apply concurrency to a single threaded program. There is only one thread in a single-threaded application. When you call a blocking method, it will block until it returns. The caller cannot unblock it after calling it. The way to return from a while loop is to break out of the loop:

while (true) {
    if (some_condition) { return; }
    //do something...
}

You can inject the condition via a callable:

template <typename F>
void doSomething(F stop_condition) {
    while (true) {
        if (stop_condition()) { return; }
        //do something...
    }
}
英文:

Frankly, you are making this more complicated than necessary by trying to apply concurrency to a single threaded program. There is only one thread in a single threaded application. When you call a blocking method it will block until it returns. The caller cannot unblock it after calling it. The way to return from a while loop is to break out of the loop:

  while(true) {
    if(some_condition) { return; }
    //do something...
  }

You can inject the condition via a callable:

template &lt;typename F&gt;
void doSomething(F stop_condition) {
  while(true) {
    if(stop_condition()) { return; }
    //do something...
  }
}

huangapple
  • 本文由 发表于 2023年5月31日 23:19:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76375048.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定