【发布时间】:2021-01-09 21:16:39
【问题描述】:
我正在编写一个程序,并为SIGINT 设置了一个信号处理程序:
volatile int exit_program = 0; //Global variable
void exit_client() {
write(1, "Disconnecting...\n", strlen("Disconnecting...\n"));
exit_program = 1;
}
然后我主要告诉进程在收到SIGINT 时对exit_client() 做出反应。
int main() {
signal(SIGINT, exit_client);
//...
}
稍后在主进程中我有以下代码:
while (!exit_program) {
//...
socket_rcv(server_socket);
}
close(server_socket);
write(1, "Disconnected\n", strlen("Disconnected\n"));
我使用socket_rcv() 从服务器套接字接收数据,如果read() 返回值为0(当服务器断开连接时),我还向进程发送SIGINT。我这样做执行:raise(SIGINT):
socket_data socket_rcv(int socket) {
//...
do {
bytes_read = read(socket, sequence + (115 - total_bytes), total_bytes+10);
if (bytes_read == -1) write(1, "Read error\n", strlen("Read error\n"));
if (bytes_read == 0) raise(SIGINT);
total_bytes -= bytes_read;
} while (total_bytes > 0);
//...
}
但是,当同时执行服务器和客户端并首先断开服务器连接时,看看客户端如何反应(应该打印Disconnecting... 然后Disconnected 以及服务器套接字关闭),我只得到打印信号处理程序确认信号处理程序执行但随后程序终止并且它不会继续执行以关闭套接字并执行最后一个write(1, "Disconnected\n", strlen("Disconnected\n"));。
为什么会终止,我该如何解决?
另外,可能无关紧要,但 socket_rcv() 函数在另一个 .c 文件中声明,包括主进程所在的 .h 模块。
【问题讨论】:
-
为什么需要信号?为什么不直接设置
exit_program? -
你能创建一个minimal reproducible example吗?
-
请注意,一般情况下最好使用
sigaction而不是signal。 -
@kaylum 因为程序直到我按下
CTRL + C才会结束,这会向该进程发送SIGINT然后退出循环并free()使用内存并关闭一些文件描述符 -
不确定按 Ctrl+C 是否适合图片,您可能希望将其整合到整个故事中。请注意
signal()正在安装一次性处理程序,如果您获得两个信号,第二个将使用默认处理程序并立即核对进程。raise不会退出 socket_rcv 函数,所以你可能会得到断开连接的打印,回到被困在socket_rcv中,然后按 ^C 并见上文。
标签: c signal-handling