具有更多参数的信号处理程序
Signal handler with more parameters
我正在 Ubuntu 18.04.2 LTS 上使用 ROS Melodic 和 Gazebo 9.9.0。
我想在用户杀死节点时向机器人发送 "stop" 消息(全为零的 Twist 消息)。
为了处理 Ctrl.+C 事件,我使用这个:
/**
* Override the default ros sigint handler to stop the robot when user press
* Ctrl.+C.
*/
void sigintHandler(int sig)
{
// All the default sigint handler does is call shutdown()
ros::shutdown();
}
但是这个函数不允许传递更多的参数(我需要传递cmd_vel_pub
)。
我已在主要功能上声明此发布者:
int main(int argc, char **argv)
{
ros::init(argc, argv, "astar_controller");
ros::NodeHandle n;
// Override the default ros sigint handler.
// This must be set after the first NodeHandle is created.
std::signal(SIGINT, sigintHandler);
/**
* Topic where we are going to publish speed commands.
*/
ros::Publisher cmd_vel_pub = n.advertise<geometry_msgs::Twist>(cmdTopic, 1000);
// More code...
}
也许我可以将 cmd_vel_pub
声明为全局。
有什么方法可以将更多参数传递给 sigintHandler
还是我需要将其声明为全局参数?
可以从信号处理程序调用的函数列表有限,请参阅 man signal-safety
。因此,从信号处理程序上下文中发送 Twist 消息可能是不可能的。
self-pipe trick常用于处理信号处理上下文之外的信号:
Maintain a pipe and select for readability on the pipe input. Inside the signal handler, write a byte (non-blocking, just in case) to the pipe output. Done.
除此之外,我建议将信号编号字节写入管道,这样您就可以对任何信号(如果适用)使用完全相同的信号处理程序和管道。
希望处理信号的线程必须等待管道的读取端变为可读,读取该字节并处理信号。可以使用事件循环(例如 select
、epoll
等)或阻塞 read
调用来完成等待。
或者,您可以使用 signalfd
代替管道(请参阅此处的示例)。或 sigsuspend
阻塞并等待信号。
我正在 Ubuntu 18.04.2 LTS 上使用 ROS Melodic 和 Gazebo 9.9.0。
我想在用户杀死节点时向机器人发送 "stop" 消息(全为零的 Twist 消息)。
为了处理 Ctrl.+C 事件,我使用这个:
/**
* Override the default ros sigint handler to stop the robot when user press
* Ctrl.+C.
*/
void sigintHandler(int sig)
{
// All the default sigint handler does is call shutdown()
ros::shutdown();
}
但是这个函数不允许传递更多的参数(我需要传递cmd_vel_pub
)。
我已在主要功能上声明此发布者:
int main(int argc, char **argv)
{
ros::init(argc, argv, "astar_controller");
ros::NodeHandle n;
// Override the default ros sigint handler.
// This must be set after the first NodeHandle is created.
std::signal(SIGINT, sigintHandler);
/**
* Topic where we are going to publish speed commands.
*/
ros::Publisher cmd_vel_pub = n.advertise<geometry_msgs::Twist>(cmdTopic, 1000);
// More code...
}
也许我可以将 cmd_vel_pub
声明为全局。
有什么方法可以将更多参数传递给 sigintHandler
还是我需要将其声明为全局参数?
可以从信号处理程序调用的函数列表有限,请参阅 man signal-safety
。因此,从信号处理程序上下文中发送 Twist 消息可能是不可能的。
self-pipe trick常用于处理信号处理上下文之外的信号:
Maintain a pipe and select for readability on the pipe input. Inside the signal handler, write a byte (non-blocking, just in case) to the pipe output. Done.
除此之外,我建议将信号编号字节写入管道,这样您就可以对任何信号(如果适用)使用完全相同的信号处理程序和管道。
希望处理信号的线程必须等待管道的读取端变为可读,读取该字节并处理信号。可以使用事件循环(例如 select
、epoll
等)或阻塞 read
调用来完成等待。
或者,您可以使用 signalfd
代替管道(请参阅此处的示例)。或 sigsuspend
阻塞并等待信号。