如何以非阻塞、不可中断的方式从类中运行 C++ 函数 [关闭]

Posted

技术标签:

【中文标题】如何以非阻塞、不可中断的方式从类中运行 C++ 函数 [关闭]【英文标题】:How to run a c++ function from a class in a non-blocking non-interruptable way [closed] 【发布时间】:2021-01-29 20:21:23 【问题描述】:

我有一个 c++ 问题,我不知道该问什么,考虑到我几周的 c++ 经验,什么可能是最好的解决方案。

给定一个 c++ 类,我在其中一个函数中初始化以下对象:

franka::Robot robot(robot_ip);

在我到达其他几行之后:

robot.control(callback);

它启动了一个不间断的内部 While 循环,并保持代码在这一行被阻塞。但是,我仍然想继续使用这个类的另一个函数,因为代码在最后一行被阻止了,所以现在不可能。

有没有办法让 C++ 在后台或在单独的进程或线程中以非阻塞方式执行最后一行,然后继续执行剩余的行?

我也不确定每种方式的优势是什么。例如,我可以想象有可能在单独的进程或单独的线程或其他方式中执行此操作,同时不知道哪个可能是最好的,并希望它们的语法很简单。但是我知道速度可能至关重要,我们不希望中断这个内部循环。

我查看了一些其他问题,例如 in this thread,但我很困惑如果我要使用它们,我该如何修改我的语法,或者即使可能也不确定。

-----编辑::

我尝试了std::thread([]() robot.control(torque_control_cb); ).detach(); 作为here 的答案,但出现以下错误:

5: error: ‘robot’ is not captured
       std::thread([]() robot.control(callback); ).detach();

将该行更改为std::thread t1(robot.control, callback); 也会出现错误:

 error: no matching function for call to ‘std::thread::thread(<unresolved overloaded function type>, std::function<franka::Torques(const franka::RobotState&, franka::Duration)>&)’
       std::thread t1(robot.control, callback)

同样:

   error: ‘async’ is not a member of ‘std’
     auto result = std::async(std::launch::async, []()robot.control(callback););

【问题讨论】:

“最佳”解决方案完全取决于您的要求。您可以删除内部循环并使其成为您从“外部”调用的更新函数,从而控制分配给此函数的时间片,如果您想保持单线程。您可以生成一个新线程并让它在那里运行。你可以在一个完全独立的进程等中运行它。如果没有更深入地了解它要解决的问题,很难推荐一些东西。 @odyss-jii 删除内部循环对我来说不是一个好的解决方案,因为它需要更改包的源代码并且也很困难。单独的线程或进程听起来更好,哪个更容易修改代码? 你应该打开你的 C++ 教科书到解释如何使用std::thread 的那一章,你会在那一章找到你需要的所有信息。 【参考方案1】:

这是一个如何在后台运行函数的示例:

#include <chrono>
#include <functional>
#include <iostream>
#include <thread>

void run(int& status) noexcept

  while (true) 
    ++status;
    std::this_thread::sleep_for(std::chrono::seconds(1));
  


int main()

  int x = 0;
  std::cout << "Lauch new thread" << std::endl;
  std::thread newthread(std::function<void(int&)>(run), std::ref(x));
  std::cout << "x = " << x << std::endl;
  std::string s;
  std::cout << "Enter to continue";
  std::cin.ignore();
  std::cout << "x = " << x << std::endl;
  newthread.detach();

  return 0;

初始化后,run(int&amp;) 在后台运行,每秒增加一次x。根据您按下 Enter 后等待的时间,您会得到不同的当前值 x

注意:我将run 包装成std::function 以便能够将其传递给std::thread 的构造函数,但您也可以在适当位置编写一个lambda

std::thread newthread([](int &s)  run(s); , std::ref(x));

另外,请注意我必须将xstd::ref 包装起来才能将其传递给std::thread 的构造函数,请参阅here。

或者,如果您想使用直接使用 x 的 lambda,您需要 capture it:

#include <chrono>
#include <iostream>
#include <thread>

int main()

  int x = 0;
  std::cout << "Lauch new thread" << std::endl;
  std::thread newthread([&]() 
    while (true) 
      ++x;
      std::this_thread::sleep_for(std::chrono::seconds(1));
    
  );
  std::cout << "x = " << x << std::endl;
  std::string s;
  std::cout << "Enter to continue";
  std::cin.ignore();
  std::cout << "x = " << x << std::endl;
  newthread.detach();

  return 0;

【讨论】:

以上是关于如何以非阻塞、不可中断的方式从类中运行 C++ 函数 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何以非阻塞方式压缩文件

Spring如何以非阻塞方式匹配bcrypt密码

如何以非阻塞方式链接期货?也就是说,如何在不阻塞的情况下将一个future用作另一个future的输入?

C++ 从类中调用重载运算符

以非阻塞方式打开 QDialog

以非阻塞方式等待 CIContext 渲染任务