c++ Lely CANopen中的AsyncWait不是异步行为?

tyky79it  于 2022-11-27  发布在  其他
关注(0)|答案(1)|浏览(140)

我正在尝试使用Lely CANopen堆栈中的光纤执行一些任务。但是,我要么不理解模型,要么有什么东西坏了。我想做的是以不同的速率运行多个任务。
基于教程here的示例:

class MyDriver : public canopen::FiberDriver {
 public:
  using FiberDriver::FiberDriver;

 private:
  // Configure device
  void OnConfig(std::function<void(std::error_code ec)> res) noexcept override {
    try {
      // Do some SDO configuration

      // Schedule tasks
      Defer(&MyDriver::TaskA, this);
      Defer(&MyDriver::TaskB, this);

      // Return no error
      res({});
    } catch (canopen::SdoError& e) {
      res(e.code());
    }
  }

  void TaskA() noexcept {
    while (true) {
      // Do some processing
      std::cout << "Hello from task A" << std::endl;

      // Wait
      Wait(AsyncWait(duration(std::chrono::milliseconds(1000))));
    }
  }

  void TaskB() noexcept {
    while (true) {
      // Do some processing
      std::cout << "Hello from task B" << std::endl;

      // Wait
      Wait(AsyncWait(duration(std::chrono::milliseconds(500))));
    }
  }

};

int main() {
  // A lot of set up omitted for clarity
  // Create context, event loop, CAN channel, etc.

  // Create master
  canopen::AsyncMaster master(timer, chan, "../config/master.dcf", "", 1);

  // Start NMT service by pretending to get a reset command
  master.Reset();

  // Create a driver for CAN device
  MyDriver driver(exec, master, 2);

  // Run the event loop
  loop.run();

  return 0;
}

我希望这会打印出类似如下的内容:

Hello from task A
Hello from task B
Hello from task B
Hello from task A
Hello from task B
Hello from task B
...

但是,我得到的输出如下所示:

Hello from task A
Hello from task A
Hello from task A
Hello from task A
...

所以看起来Wait(AsyncWait(d))实际上并没有产生执行。我做错了什么?

bfrts1fy

bfrts1fy1#

Answered here,但在下面重复,以便于查找。)
这是因为您使用Defer()而不是Post()来排定任务的日程。
Defer()将任务提交给“strand”执行器。strand保证提交给它的任务永远不会并发运行。因此,它只会在任务A完成后执行任务B。这在多线程应用程序(例如使用LoopDriver时)中非常有用,可以在不必使用互斥或其他显式同步机制的情况下防止争用情况。
Defer()可能不是最明显的名称。它最初来自Boost.Asio中的执行程序,表示提交的任务不会与执行提交的任务(在您的示例中为OnConfig())同时运行。在本例中,它的意思是“延迟任务A直到OnConfig()完成,延迟任务B直到任务A完成”。

相关问题