2011-06-06 20 views
12

मेरे कार्यक्रम इस तरह एक पाश के माध्यम से चला जाता है:अवरुद्ध दखल पढ़

... 
while(1){ 
    read(sockfd,buf,sizeof(buf)); 
    ... 
} 

पढ़ने समारोह ब्लॉक यह इनपुट है, जो एक सॉकेट से होने वाला इंतज़ार कर रहा है जब। मैं SIGINT को संभालना चाहता हूं और मूल रूप से इसे पढ़ने के फ़ंक्शन को रोकने के लिए कहता हूं यदि यह पढ़ रहा है और फिर मनमाने ढंग से कार्य करें। इसे करने का बेहतरीन तरीका क्या है?

उत्तर

14
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 
आप क्या प्रदान की है के साथ
+0

, SIGINT भेजना (Ctrl + C के माध्यम से) प्रोग्राम को समाप्त करता है। – kaykun

+0

@ कयकुन, केवल अगर यह कार्यक्रम में आखिरी पंक्ति है। ट्रांसमिशन को दोबारा शुरू करने वाले 'थ्रू' ब्लॉक के बाद आप और लाइनें जोड़ सकते हैं, आप उस विशिष्ट क्लाइंट को छोड़ सकते हैं और अपने प्रोग्राम के मेनलोप के साथ जारी रख सकते हैं, आप उपयोगकर्ता के साथ एक इंटरैक्टिव खोल शुरू कर सकते हैं कि आगे क्या कदम उठाने हैं ... कुछ भी नहीं कहता है कि इसे कार्यक्रम को समाप्त करना है। – sarnold

+0

@ कर्नाल्ड गलत, कम से कम मेरे लिए कार्यक्रम समाप्त हो जाता है जब SIGINT भेजा जाता है इससे कोई फर्क नहीं पड़ता कि मैं लूप के बाद क्या जोड़ता हूं, जो लगभग सभी अन्य कमांड लाइन प्रोग्रामों के लिए भी समान है। – kaykun

2

जब आपकी प्रक्रिया सिग्नल प्राप्त करती है, read() वापस आ जाएगी और errno का मान EINTR पर सेट किया जाएगा।