

执行到while(1)进入循环体内oset这个信号集一直不变应该是原来默认的信号屏蔽字才对也就是不屏蔽任何信号,而sigsuspend把oset指定的信号集替换当前进程的信号集,所以以后一直不屏蔽信号才对,但是我终端上按Ctrl+c发送信号却无法打出感叹号,


以下内容由AIGC及阿里嘎多学长共同生成、有用望采纳:
好的,让我们一步步来解决这些问题。
sigprocmask 函数用于改变进程的信号屏蔽字。它有三个参数:
how:指定如何改变信号屏蔽字。可以是 SIG_BLOCK、SIG_UNBLOCK 或 SIG_SETMASK。set:指向要改变的信号集。oldset:指向存储旧信号屏蔽字的位置。sigsuspend 函数用于挂起进程直到接收到信号。它需要一个参数,即信号集。在调用 sigsuspend 之前,需要确保信号集已经被正确设置。
从你提供的代码和描述来看,程序在接收到SIGINT信号时,应该调用 int_handler 函数并打印出感叹号。但实际运行时没有触发预期的行为。这可能是由于信号集设置不正确或信号处理函数没有被正确注册。
你的 int_handler 函数如下:
static void int_handler(int s) {
write(1, "!", 1);
}
这个函数看起来是正确的,它在接收到信号时会向标准输出写入一个感叹号。
信号处理函数的响应可能会受到程序中其他代码的影响。确保没有其他代码阻塞信号处理。
从你提供的代码中,可以看到一些可能的问题:
sigprocmask 函数的调用中有一些拼写错误和格式错误。write 函数的调用中参数不完整。我们可以通过添加打印语句或使用调试工具来跟踪信号处理函数的调用情况。
以下是修正后的代码示例,添加了一些打印语句来帮助调试:
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
static void int_handler(int s) {
printf("!\n");
}
int main(void) {
int i;
sigset_t set, oset, saveset;
signal(SIGINT, int_handler);
sigemptyset(&set);
sigaddset(&set, SIGINT);
// 保存初始屏蔽字
sigprocmask(SIG_BLOCK, &set, &saveset);
while(1) {
for(i = 0; i < 5; i++) {
printf("%d\n", i);
sleep(1);
}
sigsuspend(&oset);
sigprocmask(SIG_SETMASK, &saveset, NULL);
}
exit(0);
}
int_handler 函数并打印感叹号。int_handler 函数。通过这些步骤,你应该能够找出问题所在并进行修正。如果问题仍然存在,可以考虑进一步检查信号处理函数的调用情况或使用调试工具进行更深入的分析。