#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
void INThandler(int);
int main(void)
{
signal(SIGINT, INThandler);
while (1)
pause();
return 0;
}
void INThandler(int sig)
{
char c;
signal(sig, SIG_IGN);
printf("OUCH, did you hit Ctrl-C?\n"
"Do you really want to quit? [y/n] ");
c = getchar();
if (c == 'y' || c == 'Y')
exit(0);
else
signal(SIGINT, INThandler);
getchar(); // Get new line character
}
C11标准:www.example.com § 5如果信号不是作为调用abort或raise函数的结果而发生的,则如果信号处理程序引用任何具有static或线程存储持续时间的对象,而不是通过给声明为volatile sig_atomic_t的对象赋值来引用无锁原子对象,则行为是未定义的...7.14.1.1§5If the signal occurs other than as the result of calling the abort or raise function, the behavior is undefined if the signal handler refers to any object with static or thread storage duration that is not a lock-free atomic object other than by assigning a value to an object declared as volatile sig_atomic_t ...
#include<stdio.h>
#include<signal.h>
#include<unistd.h>
void sig_handler(int signo)
{
if (signo == SIGINT)
printf("received SIGINT\n");
}
int main(void)
{
if (signal(SIGINT, sig_handler) == SIG_ERR)
printf("\ncan't catch SIGINT\n");
// A long long wait so that we can easily issue a signal to this process
while(1)
sleep(1);
return 0;
}
9条答案
按热度按时间5vf7fwbs1#
有信号处理器。
下面是一个简单的示例,翻转
main()
中使用的bool
:polkgigr2#
查看此处:
上面的示例代码:
ifmq2ha23#
关于UN*X平台的增编。
根据GNU/Linux上的
signal(2)
手册页,signal
的行为不如sigaction
的行为可移植:signal()的行为在不同的UNIX版本中会有所不同,在不同的Linux版本中也会有所不同用途:而是使用sigaction(2)。
在System V上,系统不会阻止信号的进一步传递,并且传递信号会将处理程序重置为默认值。在BSD中,语义发生了变化。
Dirk Eddelbuettel之前答案的以下变体使用
sigaction
代替signal
:dhxwm5r44#
@Peter Varo更新了Dirk的答案,但Dirk拒绝了修改,以下是Peter的新答案:
虽然上面的代码片段是一个正确的c89示例,但是如果可能的话,应该使用更现代的类型和后续标准提供的保证。因此,对于那些正在寻找符合c99和c11的实现的人来说,这里有一个更安全和现代的替代方案:
<signal.h>
声明了一个类型...sig_atomic_t
,它是一个对象的整数类型(可能是volatile-qualified),可以作为原子实体访问,即使存在异步中断。此外:
abort
或raise
函数的结果而发生的,则如果信号处理程序引用任何具有static
或线程存储持续时间的对象,而不是通过给声明为volatile sig_atomic_t
的对象赋值来引用无锁原子对象,则行为是未定义的...7.14.1.1§5If the signal occurs other than as the result of calling theabort
orraise
function, the behavior is undefined if the signal handler refers to any object withstatic
or thread storage duration that is not a lock-free atomic object other than by assigning a value to an object declared asvolatile sig_atomic_t
...cwtwac6a5#
或者,您可以将终端置于原始模式,如下所示:
现在应该可以使用
fgetc(stdin)
读取Ctrl+C键击了。但是要小心使用这个,因为你不能像平常一样使用Ctrl+Z,Ctrl+Q,Ctrl+S等。x8goxv8g6#
设置陷阱(可以使用一个处理程序捕获多个信号):
您可以随心所欲地处理信号,但要注意限制和陷阱:
mzaanser7#
关于现有的答案,请注意信号处理是依赖于平台的,例如Win32处理的信号比POSIX操作系统少得多;see here。虽然SIGINT是在Win32上的signals. h中声明的,但请参阅文档中的注解,其中解释了SIGINT不会执行您可能期望的操作。
jei2mxaa8#
函数sig_handler检查传递的参数值是否等于SIGINT,然后执行printf。
lo8azlld9#
这只是在退出前打印。