12
我的程序經過這樣的循環:當它等待輸入,這恰好是從插座中斷阻止讀
...
while(1){
read(sockfd,buf,sizeof(buf));
...
}
讀取功能塊。我想處理SIGINT並基本告訴它如果正在讀取並停止讀取函數,然後調用任意函數。做這個的最好方式是什麼?
我的程序經過這樣的循環:當它等待輸入,這恰好是從插座中斷阻止讀
...
while(1){
read(sockfd,buf,sizeof(buf));
...
}
讀取功能塊。我想處理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
當您的進程收到信號時,read()
將返回並且errno
的值將設置爲EINTR
。
根據您提供什麼,發送SIGINT(通過Ctrl + C)只是結束程序。 – kaykun 2011-06-06 09:06:07
@ kaykun,只有這是程序的最後一行。您可以在重新啓動傳輸的'while'塊之後添加更多行,您可以刪除特定客戶端並繼續執行程序的主循環,您可以啓動與用戶的交互式shell,以詢問接下來要執行的操作沒有什麼說這必須終止程序。 – sarnold 2011-06-06 09:13:25
@sarnold不正確,至少對我來說,無論我在while循環後添加什麼,發送SIGINT時程序都會終止,這對幾乎所有其他命令行程序都是一樣的。 – kaykun 2011-06-06 09:21:58