【发布时间】:2011-06-06 08:47:36
【问题描述】:
我的程序会这样循环:
...
while(1){
read(sockfd,buf,sizeof(buf));
...
}
read 函数在等待输入时阻塞,该输入恰好来自套接字。我想处理 SIGINT 并基本上告诉它在读取时停止读取函数,然后调用任意函数。最好的方法是什么?
【问题讨论】:
我的程序会这样循环:
...
while(1){
read(sockfd,buf,sizeof(buf));
...
}
read 函数在等待输入时阻塞,该输入恰好来自套接字。我想处理 SIGINT 并基本上告诉它在读取时停止读取函数,然后调用任意函数。最好的方法是什么?
【问题讨论】:
来自read(2):
EINTR The call was interrupted by a signal before any data
was read; see signal(7).
如果你修改你的代码看起来更像:
cont = 1;
while (1 && cont) {
ret = read(sockfd, buf, sizeof(buf));
if (ret < 0 && errno == EINTR)
cont = arbitrary_function();
}
这让arbitrary_function() 决定是否应该重试read(2)。
更新
您需要处理信号才能从read(2) 获得EINTR 行为:
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<errno.h>
int interrupted;
void handle_int(num) {
interrupted = 1;
}
int main(void){
char buf[9001];
struct sigaction int_handler = {.sa_handler=handle_int};
sigaction(SIGINT,&int_handler,0);
while(!interrupted){
printf("interrupted: %d\n", interrupted);
if(read(0,buf,sizeof(buf))<0){
if(errno==EINTR){
puts("eintr");
}else{
printf("%d\n",errno);
}
puts(".");
}
}
puts("end");
return 0;
}
给出输出:
$ ./foo
interrupted: 0
hello
interrupted: 0
^Ceintr
.
end
【讨论】:
while 块之后添加更多行以重新启动传输,您可以删除该特定客户端并继续执行程序的主循环,您可以与用户启动一个交互式 shell,询问下一步要采取什么行动...没有什么说这必须终止程序。
SIGINT。
当您的进程收到信号时,read() 将返回,errno 的值将设置为 EINTR。
【讨论】: