为什么我在 Ubuntu 终端上发送 SIGTERM (Ctrl + C) 时我的 C++ 代码没有终止?

Why is my C++ code not terminated when I sent SIGTERM (Ctrl + C) on Ubuntu Terminal?

我写了一个程序从USB读取数据。代码如下:

#include "ros/ros.h"
#include <iostream>
#include <fstream>
#include <string>

int main(int argc, char **argv){
    ros::init(argc, argv, "read_usb");
    ros::NodeHandle nh;
    ros::Rate loop_rate(100);
    while(ros::ok()){       
        std::string str;
        std::fstream openmv_cam_h7;
        openmv_cam_h7.open("/dev/ttyACM0");     
        while(openmv_cam_h7 >> str){
            std::cout << str << std::endl;
        }
        openmv_cam_h7.close();
        ros::spinOnce();
        loop_rate.sleep();
    }
}

当我运行这个程序的时候,很顺利。但是当我想通过在 Ubuntu 终端上按 Ctrl+C (SIGTERM) 来终止它时,程序保持 运行。它仅在我拔下用于发送数据的 USB 设备时终止。

为什么会这样?发送SIGTERM信号时希望程序终止怎么办?

附加信息: 我的 OS 是 Ubuntu 18.04,我使用 ROS Melodic。

通常按 Ctrl+C 将毫无问题地终止您的程序。

以下是我的怀疑和解决方案:

  1. Ubuntu 可能有问题并且没有将 SIGTERM 发送到您的应用程序。要测试 Ubuntu 是否正常工作,请创建一个带有一个 while(true) {} 循环的空程序(永远阻塞)并测试您是否可以 CTRL+C 这个程序。如果它退出,则说明您的代码有问题。

  2. 如果第 1 点有效,那么我觉得 loop_rate.sleep() 或 ros::spinOnce() 可能会以某种方式导致捕获 SIGTERM 的问题。 sleep 或 spinOnce 可能会锁定应用程序一小段时间(谁知道)。尝试删除它们并重新测试 CTRL+C。另外,尝试多次(快速)粉碎 CTRL+C 并查看这是否会触发退出。如果这确实有效,那么您将需要弄清楚为什么 ROS / sleep() 或 spinOnce() 方法会(间歇性地)锁定您的应用程序,因此没有捕捉到 SIGTERM。

  3. ROS 可能已经将 SIGTERM 处理程序本身挂接到库中,并且可能正在用它做一些事情(显然没有退出)。如果是这种情况,您可能必须在主程序中添加自己的 SIGTERM 处理程序,这样您将捕获 CTRL+C,然后手动调用 exit()。

试试看,然后回复我们。