Linux 中断阻塞读取
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6249577/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Interrupting blocked read
提问by kaykun
My program goes through a loop like this:
我的程序经过这样的循环:
...
while(1){
read(sockfd,buf,sizeof(buf));
...
}
The read function blocks when it is waiting for input, which happens to be from a socket. I want to handle SIGINT and basically tell it to stop the read function if it is reading and then call an arbitrary function. What is the best way to do this?
read 函数在等待输入时会阻塞,这恰好来自套接字。我想处理 SIGINT 并基本上告诉它在读取时停止读取函数,然后调用任意函数。做这个的最好方式是什么?
采纳答案by sarnold
From read(2)
:
来自read(2)
:
EINTR The call was interrupted by a signal before any data
was read; see signal(7).
If you amend your code to look more like:
如果你修改你的代码看起来更像:
cont = 1;
while (1 && cont) {
ret = read(sockfd, buf, sizeof(buf));
if (ret < 0 && errno == EINTR)
cont = arbitrary_function();
}
This lets arbitrary_function()
decide if the read(2)
should be re-tried or not.
这让我们arbitrary_function()
决定是否read(2)
应该重试。
Update
更新
You need to handle the signal in order to get the EINTR
behavior from read(2)
:
您需要处理信号才能EINTR
从read(2)
以下位置获取行为:
#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;
}
Gives output:
给出输出:
$ ./foo
interrupted: 0
hello
interrupted: 0
^Ceintr
.
end
回答by Blagovest Buyukliev
When your process receives a signal, read()
will return and the value of errno
will be set to EINTR
.
当您的进程收到信号时,read()
将返回并将 的值errno
设置为EINTR
。