首页 > 解决方案 > 当我在 Ubuntu 终端上发送 SIGTERM (Ctrl + C) 时,为什么我的 C++ 代码没有终止?

问题描述

我写了一个程序来从 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 信号时终止,我应该怎么做?

附加信息:我的操作系统是 Ubuntu 18.04,我使用 ROS Melodic。

标签: c++ubuntuusbfstreamros

解决方案


通常按 Ctrl+C 将终止您的程序而不会出现任何问题。

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

  1. Ubuntu 可能有问题并且没有将 SIGTERM 发送到您的应用程序。要测试 Ubuntu 是否正常工作,请使用 ONE 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 处理程序本身,并且可能正在用它做一些事情(显然没有退出)。如果是这种情况,您可能必须在 main 中添加自己的 SIGTERM 处理程序,因此您将捕获 CTRL+C,然后手动调用 exit()。

试试这些,然后回复我们。


推荐阅读