- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个循环处理 accept(2)
调用。我希望能够在将 SIGINT
发送到程序时执行一些清理操作。我的第一个想法是使用 signal
函数。
void signal_handler(int signal) {
printf("Caught signal\n");
}
int main() {
signal(SIGINT, &signal_handler);
// ...
int accept_fd = accept(sock, NULL, NULL);
if (accept_fd == -1) {
close(sock);
perror("accept");
return 1;
}
// ...
}
但是,这只是打印“捕获信号”,然后程序继续。
如果我修改 main
以使用 sigaction
,程序将按预期工作。
int main() {
struct sigaction sa;
sa.sa_handler = &signal_handler;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(SIGINT, &sa, NULL);
// ...
int accept_fd = accept(sock, NULL, NULL);
if (accept_fd == -1) {
close(sock);
perror("accept");
return 1;
}
// ...
}
发送 SIGINT 后,我收到捕获信号
,然后收到接受:中断的系统调用
。来自 accept(2)
ERRORS
...
EINTR The system call was interrupted by a signal that was caught before a valid connection arrived; see signal(7).
我知道 sigaction
更现代,我应该使用它而不是 signal
,但我很好奇为什么它提供了这种功能差异。
下面我为每种情况提供了一个完整的可用示例程序。
#include <netdb.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFFER_SIZE 32
void signal_handler(int signal) {
printf("Caught signal\n");
}
int main() {
signal(SIGINT, &signal_handler);
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
struct addrinfo *addr_info;
int info_result = getaddrinfo("localhost", "8080", &hints, &addr_info);
if (info_result != 0) {
printf("Getting address failed\n");
return 1;
}
int sock = socket(addr_info->ai_family, addr_info->ai_socktype, addr_info->ai_protocol);
if (sock == -1) {
printf("Socket Failed\n");
return 1;
}
int bind_result = bind(sock, addr_info->ai_addr, addr_info->ai_addrlen);
if (bind_result == -1) {
close(sock);
printf("Bind Failed\n");
return 1;
}
int listen_result = listen(sock, 8);
if (listen_result == -1) {
close(sock);
printf("Listen Failed\n");
return 1;
}
printf("Waiting...\n");
int accept_fd = accept(sock, NULL, NULL);
if (accept_fd == -1) {
close(sock);
perror("accept");
return 1;
}
printf("Got fd %d\n", accept_fd);
char *buffer = malloc(BUFFER_SIZE * sizeof(char));
int n;
while ((n = read(accept_fd, buffer, BUFFER_SIZE)) > 0) {
printf("%.*s\n", n, buffer);
}
close(sock);
}
#include <netdb.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFFER_SIZE 32
void signal_handler(int signal) {
printf("Caught signal\n");
}
int main() {
struct sigaction sa;
sa.sa_handler = &signal_handler;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(SIGINT, &sa, NULL);
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
struct addrinfo *addr_info;
int info_result = getaddrinfo("localhost", "8080", &hints, &addr_info);
if (info_result != 0) {
printf("Getting address failed\n");
return 1;
}
int sock = socket(addr_info->ai_family, addr_info->ai_socktype, addr_info->ai_protocol);
if (sock == -1) {
printf("Socket Failed\n");
return 1;
}
int bind_result = bind(sock, addr_info->ai_addr, addr_info->ai_addrlen);
if (bind_result == -1) {
close(sock);
printf("Bind Failed\n");
return 1;
}
int listen_result = listen(sock, 8);
if (listen_result == -1) {
close(sock);
printf("Listen Failed\n");
return 1;
}
printf("Waiting...\n");
int accept_fd = accept(sock, NULL, NULL);
if (accept_fd == -1) {
close(sock);
perror("accept");
return 1;
}
printf("Got fd %d\n", accept_fd);
char *buffer = malloc(BUFFER_SIZE * sizeof(char));
int n;
while ((n = read(accept_fd, buffer, BUFFER_SIZE)) > 0) {
printf("%.*s\n", n, buffer);
}
close(sock);
}
最佳答案
在 BSD 和 Linux 上,signal()
相当于将 sa_flags
设置为 SA_RESTART
的 sigaction()
。如果您在 sigaction()
代码中设置该标志,它将与您的 signal()
代码表现相同。如果这不是您想要的,那么您只能使用 sigaction()
。
来自 Linux man page 的注释(也适用于 BSD 和 OS X):
On BSD, when a signal handler is invoked, the signal disposition is not reset, and further instances of the signal are blocked from being delivered while the handler is executing. Furthermore, certain blocking system calls are automatically restarted if interrupted by a signal handler (see signal(7)). The BSD semantics are equivalent to calling sigaction(2) with the following flags:
sa.sa_flags = SA_RESTART;
关于c - sigaction 将 SIGINT 传递给系统调用,但不传递信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52231219/
脚本1.sh: #!/bin/bash ./script2.sh echo after-script 脚本2.sh: #!/bin/bash function handler { exi
我正在编写一个多线程程序,我想在其中处理来自用户的可能的 Ctrl-C 命令以终止执行。据我所知,不能保证能够取消每个工作线程的主线程会捕获信号。因此,是否有必要为工作线程的代码设置一个不同的信号处理
我正在编写一个多线程程序,我想在其中处理来自用户的可能的 Ctrl-C 命令以终止执行。据我所知,不能保证能够取消每个工作线程的主线程会捕获信号。因此,是否有必要为工作线程的代码设置一个不同的信号处理
标题说明了一切。我该如何处理或捕捉 SIGINT在 Julia ?从文档中我假设我只是想 catch InterruptException使用 try/catch像下面这样块 try whil
以下是此问题的简单重现: void handler(int sig){ if(sig == SIGINT){ printf("Signal caught
鉴于此代码: #include #include #include void sigint_handler(int h) { printf("Hey! I caught a SIGINT
我正在写一个shell,现在它来控制子进程。当我在子进程中使用 signal (SIGTERM, SIG_DFL); 时, 信号 SIGINT 由 Ctrl + C 生成,该信号终止整个操作系统 sh
我正在尝试 SIGINT。我基本上希望我的程序在用户按下 control-c 时立即启动。当这种情况发生时,我将让程序制作一个管道。 现在,我决定当在信号处理程序中按下 control-c 时,它将调
我想处理来自内核的 SIGINT 信号,以便调用一个函数来优雅地关闭我的进程。 这是一个工作示例,一个线程正在等待信号,然后调用函数 handle_stop: #include #include
我有一个 bash 脚本,它启动了 2 个进程: openocd ...flags... 2>openocd.log & arm-none-eabi-gdb 在 gdb 中,使用 Ctrl+C 中断执
我有几个带有 while read line 循环的脚本,当我按下 Ctrl C 时,它们不执行我的清理功能。例如: #!/bin/bash cleanup() { stty echo exi
我想捕获从 Script-A.sh 发送到 Script-B.sh 的信号所以在 Script-A.sh 中我使用命令: (Send SIGINT to Script-B.sh) kill -2 $P
我正在尝试处理 SIGINT。 SIGINT 在我的程序中的主要目的是取消当前搜索功能并打印当前可用的结果。但是每当我 try catch SIGINT 信号时,它都会关闭我的程序。 (我搜索了这么多
我有 2 个程序(由我编写)。第一个名为“MAN”的进程将调用“D”(第二个),这是一个将在后台运行直到以某种方式终止的进程。 我想在不终止 D 的情况下终止 MAN。 我尝试使用 ctrl + c
我应该编写一个 C 程序来处理第一个带有自定义处理程序的 SIGINT,然后重置默认行为。我的自定义 SIGINT 处理程序应该只打印一条消息。这是我写的: #include #include #
如果父进程接收到 ctrl-C 信号,我一直试图阻止我的父线程杀死子进程。我已经没有想法了。 父进程已经捕捉到 SIGINT,所以我想要和现在 child 死了一样。 int main() {
我对Python很陌生,所以如果这个问题非常基本,请原谅我。 我试图在使用选择模块从套接字接受数据时处理键盘中断。因此,我有一个 select.select() 函数调用来等待来自套接字的数据,然后将
我无法理解为什么我的 SIGINT 从未被下面的代码捕获。 #!/usr/bin/env python from threading import Thread from time import sl
我正在编写以下代码。该程序应该能够使用 sigaction 处理 SIGINT。到目前为止,它几乎完成了,但我遇到了两个问题。 第一个问题是如果程序在 3 秒内收到 3 个信号,它应该打印“正在关闭”
在 C 中,我想捕获 SIGINT 信号并打印出类似这样的消息通过使用 sigaction 并通过 向其传递新的处理程序来“接收到 SIGINT” sa.sa_sigaction = handler;
我是一名优秀的程序员,十分优秀!