Dir*_*tel 193
带信号处理程序.
这是一个简单的例子翻转bool用于main():
#include <signal.h>
static volatile int keepRunning = 1;
void intHandler(int dummy) {
keepRunning = 0;
}
// ...
int main(void) {
signal(SIGINT, intHandler);
while (keepRunning) {
// ...
Run Code Online (Sandbox Code Playgroud)
2017年6月编辑:可能会引起关注,尤其是那些对编辑此答案抱怨无法满足的人.看,我七年前写了这个答案.是的,语言标准会发生变化 如果你真的必须改善世界,请添加你的新答案,但保留原样.由于答案上有我的名字,我更喜欢它也包含我的话.谢谢.
icy*_*com 46
点击这里:
注:显然,这是一个简单的例子解释只是如何建立一个CtrlC处理程序,但一如既往有需要,为了不打破别的东西被遵守的规则.请阅读以下评论.
上面的示例代码:
#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
}
Run Code Online (Sandbox Code Playgroud)
Fil*_* J. 29
关于UN*X平台的附录.
根据signal(2)GNU/Linux上的手册页,行为signal不像以下行为那样可移植sigaction:
signal()的行为在UNIX版本中各不相同,并且在不同版本的Linux上也有不同的历史变化.避免使用:改为使用sigaction(2).
在System V上,系统没有阻止信号的其他实例的传递,并且信号的传递会将处理程序重置为默认处理程序.在BSD中,语义发生了变化.
Dirk Eddelbuettel先前回答的以下变体使用sigaction而不是signal:
#include <signal.h>
#include <stdlib.h>
static bool keepRunning = true;
void intHandler(int) {
keepRunning = false;
}
int main(int argc, char *argv[]) {
struct sigaction act;
act.sa_handler = intHandler;
sigaction(SIGINT, &act, NULL);
while (keepRunning) {
// main loop
}
}
Run Code Online (Sandbox Code Playgroud)
MCC*_*CCS 15
@Peter Varo更新了 Dirk 的回答,但 Dirk 拒绝了更改。这是彼得的新答案:
虽然上面的代码片段是一个正确的c89示例,但如果可能的话,应该使用较新的类型和更高版本的标准提供的保证。因此,对于那些寻求符合c99和c11 的实现的人来说,这是一个更安全、更现代的替代方案:
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
static volatile sig_atomic_t keep_running = 1;
static void sig_handler(int _)
{
(void)_;
keep_running = 0;
}
int main(void)
{
signal(SIGINT, sig_handler);
while (keep_running)
puts("Still running...");
puts("Stopped by signal `SIGINT'");
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
C11 标准:7.14§2标头
<signal.h>声明了一个类型......sig_atomic_t它是一个对象的(可能是 volatile 限定的)整数类型,即使存在异步中断,也可以作为原子实体访问。
此外:
C11 标准:7.14.1.1§5如果信号不是作为调用
abortorraise函数的结果而发生的,则如果信号处理程序引用任何具有static或线程存储持续时间不是无锁原子对象的对象,则行为未定义而不是通过为声明为volatile sig_atomic_t...的对象赋值
Wal*_*ter 12
或者您可以将终端设置为原始模式,如下所示:
struct termios term;
term.c_iflag |= IGNBRK;
term.c_iflag &= ~(INLCR | ICRNL | IXON | IXOFF);
term.c_lflag &= ~(ICANON | ECHO | ECHOK | ECHOE | ECHONL | ISIG | IEXTEN);
term.c_cc[VMIN] = 1;
term.c_cc[VTIME] = 0;
tcsetattr(fileno(stdin), TCSANOW, &term);
Run Code Online (Sandbox Code Playgroud)
现在应该可以使用读取Ctrl+ C击键fgetc(stdin).请注意使用它,因为你不能正常使用Ctrl+ Z,Ctrl+ Q,Ctrl+ S等.
Pau*_*ham 11
设置一个陷阱(你可以用一个处理程序捕获几个信号):
signal (SIGQUIT, my_handler); signal (SIGINT, my_handler);
处理您想要的信号,但要注意限制和陷阱:
void my_handler (int sig)
{
/* Your code here. */
}
| 归档时间: |
|
| 查看次数: |
165147 次 |
| 最近记录: |