我正在编写一个在套接字上侦听消息的进程。收到消息后,它将执行硬件操作。完成后,它将循环返回并再次在套接字上侦听另一条消息。
当前,我已对其进行了设置,以便只要正确执行了硬件操作,它就会永远运行。
我有2个问题:
这是设计流程的正确/最佳方法吗?永远跑? (本质上是无限循环吗?
我注意到当我使用CTRL-C退出程序时。在终端中,它退出,但是ps -ef仍显示进程正在运行。彻底终止该进程并释放其使用的所有资源的最佳方法是什么?
while ((result == OK) && (m_result == OK))
{
/* Listen on the socket */
result = client_sock.NMT_read_socket(&rx_message);
if (result == OK)
{
/* Parse the message as JSON Object */
reader.parse(rx_message, mc);
if (rmct_validate_robot_action(mc))
{
/* Process Request */
m_result = rmct_obj.process_motor_action(mc["motor"].asString(), mc["direction"].asString(),
mc["angle"].asDouble(), mc["speed"].asInt());
/* Send Acknowledgement */
ack["result"] = m_result;
result = server_sock.NMT_write_socket((char *)(ack.toStyledString()).c_str());
}
free(rx_message);
}
}
在设置完所有内容后,在int main()中,我仅调用运行上述循环的方法:
/* 5. Start the Program */
cout << "RMCT Executed .............. " << endl;
rmct_main_loop(server_sock, client_sock, rmct_obj);
虽然我大部分时间都在主循环中,但大部分时间都将花费在NMT_read_socket上,而我只是坐在套接字上,等待传入消息采取行动。
内部NMT_read_socket
:
int nbytes = recvfrom(this->sock, msgbuf, MAX_BUFFER_SIZE,
0,
(struct sockaddr *) &(this->my_address),
&(adder_len)
);
if (nbytes < 0)
{
result = NOK;
NMT_log_write(WARNING, (char *)"No Message recived on socket");
}
else
{
msgbuf[nbytes] = '\0';
*message = (char *)malloc((sizeof(char) * strlen(msgbuf)) + 1);
strcpy(*message, msgbuf);
}
永远运行可能是完全合理的!
这听起来很奇怪,但是在Linux systemd
上可以为您处理套接字监视。您的进程将按需启动,可以做它的事情,并且当套接字上没有任何待处理的消息时退出。
如果您知道收到最后一条消息后再停留几秒钟很有用,因为会收到更多消息,那么您可以这样做。只要您正在处理套接字,systemd就不会。
停止也可以通过systemd处理。显然,只要您的进程未在运行,停止都是很简单的。但是,如果您可以停止正在运行的进程,则服务配置文件会告诉systemd如何。默认情况下,它将发送SIGTERM
和SIGKILL
。但是,如果对您来说更简单,则可以向您的UDP套接字发送消息。 (显然检查该消息是否来自本地主机!)