微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

O_ASYNC停止产生SIGIO

这有点长…对于初学者我在Linux 2.6.33,gcc 4.4.4。

我写了一个小程序,创build一个命名pipe道并读取它,直到它看到一个特定的string,然后它摆脱FIFO,并重新执行自己。

#include<unistd.h> #include<fcntl.h> #include<signal.h> #include<sys/types.h> #include<sys/stat.h> int fifo; #define put(x) write(1,x,(sizeof x)-1) void reader(int a) { char buf[26]; int n; while((n=read(fifo,buf,25))>0){ buf[25] = ''; if(!strncmp(buf,"moo",3)){ put("exec()-ingn"); close(fifo); unlink("lefifo"); execl("/home/dave/a.out","a.out",0); } write(1,n); } } main() { signal(SIGIO,reader); mknod("lefifo",0600|S_IFIFO,0); fifo = open("lefifo",O_RDONLY|O_NONBLOCK ); fcntl(fifo,F_SetoWN,getpid()); fcntl(fifo,F_SETFL,O_ASYNC); for(;;) pause(); }

编译后,在后台运行,我可以回lefifo ,它按预期工作,直到我input一个string开始“moo”。 以下示例会话:

$ gcc fifo.c $ ./a.out& $ echo klar > lefifo klar $ echo moo > lefifo exec()-ing $ echo klar2 > lefifo $ echo where did you go > lefifo $ echo moo > lefifo $ pkill a.out

产生这个痕迹(一些脂肪修剪):

我可以发送SIGCONT到正在运行的进程吗?

正确使用易失性sig_atomic_t

一个进程可以通过一个systemtap探针停止,所以gdb可以连接?

在Windows应用程序中捕获CTRL + BREAK

closures控制台时如何正确处理SIGBREAK?

execve("./a.out",["./a.out"],[/* 36 vars */]) = 0 mknod("lefifo",S_IFIFO|0600) = 0 open("lefifo",O_RDONLY|O_NONBLOCK) = 3 getpid() = 3945 fcntl(3,3945) = 0 fcntl(3,O_RDONLY|O_ASYNC) = 0 pause() = ? ERESTARTNOHAND (To be restarted) --- SIGIO (I/O possible) @ 0 (0) --- read(3,"klarn"...,25) = 5 write(1,5) = 5 read(3,""...,25) = 0 sigreturn() = ? (mask Now []) pause() = ? ERESTARTNOHAND (To be restarted) --- SIGIO (I/O possible) @ 0 (0) --- read(3,"moon"...,25) = 4 write(1,"exec()-ingn"...,13) = 13 close(3) = 0 unlink("lefifo") = 0 execve("/home/dave/a.out",["a.out"],O_RDONLY|O_ASYNC) = 0 pause() = ? ERESTARTNOHAND (To be restarted) --- SIGTERM (Terminated) @ 0 (0) ---

正如你所看到的,第一次做FIFO的时候没有问题,SIGIO生成的很好; 但在exec() ,新的FIFO将不会生成任何信号。 旧的显示成功closures,似乎成功删除

我很困惑为什么它可能会这样。 有任何想法吗?

中断读取()信号

为什么在Linux信号处理中遇到意外的行为?

即使在Cygwin上,Python信号也不起作用?

放弃使用信号的function实现

在LINUX C / C ++中,哪些系统调用是可中断的(即errno == EINTR)?

当你用signal()安装一个信号处理程序时,在认配置中,glibc会给BSD信号语义:在信号处理程序执行时信号被阻塞,返回时解除阻塞。

当您从信号处理程序调用exec()时,信号处理程序不会返回,所以SIGIO保持阻塞状态。 进程信号掩码在exec()上被继承,所以它在进程的新实例中仍然被阻塞。

在main()的开始处使用sigprocmask()显式解除SIGIO阻塞,你应该得到你之后的行为。

一个信号处理程序被调用时,信号被阻塞直到信号处理程序被执行。一旦信号处理程序完成,调用sigreturn()来解除信号的阻塞。 你可以在你的工作案例中看到。 但是,当你输入'moo'时,你正在从信号处理程序中调用execl,并且execl()不会返回,所以信号处理程序不会返回。 如果信号处理程序不返回,sigreturn()将不会被调用,信号将不会从块列表中删除

你可以看到使用cat / proc //状态的信号状态。 你运行你的程序,并看到/ proc //状态,在那里你可以看到sigio正在等待,也被阻止。

访问www.rulingminds.com Linux内核文章

我会建议execl (或任何其他处理)应该被移出信号处理程序。 您可以在信号处理程序中设置一个标志并在其中进行轮询。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐