为啥不能在信号处理的时候使用系统调用?

系统调用被信号打断,跟信号处理函数不能调系统调用,是两回事好吧。你现在遇到的情况是,调用系统调用进入内核,accpet还没有等到客户端建链时,就来信号,接着处理信号,信号处理完之后,accept系统调用就返回,出错码是EINTR,表明被信号打断了,这很正常呀。在POSIX规范里面很多libc函数就会被信号打断,并且不会重入,需要programmer根据具体情况做处理的。
■网友
首先明确一点:只有当子线程结束的时候会发送SIGCHLD信号给父进程。如果你accept的子线程发出了SIGCHLD信号,那么说明子线程结束了(正常或异常退出)。然后待父进程收到该信号,并做了些处理后。子线程的资源就被完全释放了,肯定阻塞就不再了。。
■网友
【为啥不能在信号处理的时候使用系统调用?】 系统的慢系统调用会被信号打断,而不是所有的系统调用都会被信号打断。
慢系统调用来描述那些可能永远堵塞的系统调用,如:accept,read,等。
当慢系统调用接收到信号的时候,系统调用可能返回一个EINTR错误,多进程的服务器中,为了避免accept被子进程信号打断,需要自己在accept返回-1的情况下,判断errno是否为EINTR,并且重启accept。
在unp中,已经将accept的这项措施在错误处理封装为Accept了,直接调用unp.h,所以很多人在学习的时候没有注意到。
类似以下,不过源文好像用的是goto,我个人不喜欢goto,continue一样的效果
while( 1 ) { clilen = sizeof(claddr); if((connfd = accept(listenfd, (SA *)\u0026amp;claddr, \u0026amp;cllen)) \u0026lt; 0) { if(errno == EINTR) continue; else err_sys("accept error"); }}

■网友
你可以在“父进程处理信号的时候”这个处理函数中下个断点打印一下栈应该就知道了。
■网友
accept本身就是系统调用


    推荐阅读