WiS*_*GaN 7 linux bash signals sigint
我一直在研究Linux中的信号.我已经完成了一个捕获SIGINT的测试程序.
#include <unistd.h>
#include <signal.h>
#include <iostream>
void signal_handler(int signal_no);
int main() {
signal(SIGINT, signal_handler);
for (int i = 0; i < 10; ++i) {
std::cout << "I'm sleeping..." << std::endl;
unsigned int one_ms = 1000;
usleep(200* one_ms);
}
return 0;
}
void signal_handler(int signal_no) {
if (signal_no == SIGINT)
std::cout << "Oops, you pressed Ctrl+C!\n";
return;
}
Run Code Online (Sandbox Code Playgroud)
输出看起来像这样:
I'm sleeping...
I'm sleeping...
^COops, you pressed Ctrl+C!
I'm sleeping...
I'm sleeping...
^COops, you pressed Ctrl+C!
I'm sleeping...
^COops, you pressed Ctrl+C!
I'm sleeping...
^COops, you pressed Ctrl+C!
I'm sleeping...
^COops, you pressed Ctrl+C!
I'm sleeping...
I'm sleeping...
I'm sleeping...
Run Code Online (Sandbox Code Playgroud)
我知道当按Ctrl + C时,前台进程组中的进程都会收到一个SIGINT(如果没有进程选择忽略它).
那么shell(bash)和上面程序的实例都收到了信号吗?每个"哎呀"之前的"^ C"来自哪里?
操作系统是CentOS,shell是bash.
wil*_*ser 10
拦截^ C并将其转换为发送到附加进程(即shell)的信号的终端(驱动程序)stty intr ^B将指示终端驱动程序拦截^ B.它也是将^ C回送到终端的终端驱动程序.
shell只是一个位于该行另一端的进程,并通过终端驱动程序(例如/ dev/ttyX)从终端接收它的stdin,并且它的stdout(和stderr)也附加到同一个tty .
需要注意的是(如果启用呼应)终端发送的击键两者的处理(组)并返回到终端.stty命令只是包含ioctl()的包装,用于进程"控制"tty的tty驱动程序.
更新:为了证明shell没有参与,我创建了以下小程序.它应该由它的父shell执行exec ./a.out(无论如何,它看起来交互式shell会分叉一个子shell)程序将生成SIGINTR的键设置为^ B,关闭echo,然后等待stdin的输入.
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
int thesignum = 0;
void handler(int signum);
void handler(int signum)
{ thesignum = signum;}
#define THE_KEY 2 /* ^B */
int main(void)
{
int rc;
struct termios mytermios;
rc = tcgetattr(0 , &mytermios);
printf("tcgetattr=%d\n", rc );
mytermios.c_cc[VINTR] = THE_KEY; /* set intr to ^B */
mytermios.c_lflag &= ~ECHO ; /* Dont echo */
rc = tcsetattr(0 , TCSANOW, &mytermios);
printf("tcsetattr(intr,%d) =%d\n", THE_KEY, rc );
printf("Setting handler()\n" );
signal(SIGINT, handler);
printf("entering pause()\n... type something followed by ^%c\n", '@'+THE_KEY );
rc = pause();
printf("Rc=%d: %d(%s), signum=%d\n", rc, errno , strerror(errno), thesignum );
// mytermios.c_cc[VINTR] = 3; /* reset intr to ^C */
mytermios.c_lflag |= ECHO ; /* Do echo */
rc = tcsetattr(0 , TCSANOW, &mytermios);
printf("tcsetattr(intr,%d) =%d\n", THE_KEY, rc );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
intr.sh:
#!/bin/sh
echo $$
exec ./a.out
echo I am back.
Run Code Online (Sandbox Code Playgroud)
shell ^C会回显您键入的所有内容,因此当您键入时,它也会被回显(在您的情况下由您的信号处理程序拦截).stty -echo根据您的需要/约束,该命令可能对您有用,也可能没有用,有关详细信息,请参阅stty的手册页.
在较低的水平,当然更推移,任何时候你经由外围设备的设备驱动程序与系统通信(如您使用以产生^ C信号键盘驱动程序,以及显示一切终端驱动程序)参与.您可以更深入地了解汇编/机器语言,寄存器,查找表等级别.如果您想要更详细,更深入的理解,下面的书籍是一个很好的起点:
Unix操作系统的设计是这类事物的一个很好的参考.另外两个经典参考:UNIX环境中的Unix编程环境 和高级编程
这个问题的好总结在这个问题中,Ctrl-C如何终止子进程?
"当你运行程序时,例如find,shell:
| 归档时间: |
|
| 查看次数: |
2731 次 |
| 最近记录: |