stdin

2010-09-14 15 views
10

पढ़ने के लिए टाइमआउट सेट करें क्या कार्यक्रम के लिए लंबे समय तक लटकने के लिए स्टडीन से पढ़ने का कोई तरीका नहीं है?stdin

read(0, var, numberofbytes); 

उत्तर

10

आप ncurses उपयोग कर सकते हैं या यदि आप नहीं करना चाहते हैं, तो आप का चयन इस blog post में वर्णित के रूप में उपयोग कर सकते हैं। असल में, आप select का उपयोग कर सकते हैं और टाइमआउट निर्दिष्ट कर सकते हैं। यदि stdin एफडी सेट है, तो आप इसे सुरक्षित रूप से पढ़ सकते हैं और ब्लॉक नहीं करेंगे। यदि आप चयन पर अधिक जानकारी चाहते हैं, तो this बाहर और निश्चित रूप से wikipedia देखें। यह जानने के लिए एक आसान कॉल है।

संपादित करें: मुझे कोड की आपूर्ति करने के लिए मजबूर होना पड़ता है, इसलिए यहां कुछ टिप्पणियों के साथ ब्लॉग पोस्ट से सीधे यह है।

// if != 0, then there is data to be read on stdin 
int kbhit() 
{ 
    // timeout structure passed into select 
    struct timeval tv; 
    // fd_set passed into select 
    fd_set fds; 
    // Set up the timeout. here we can wait for 1 second 
    tv.tv_sec = 1; 
    tv.tv_usec = 0; 

    // Zero out the fd_set - make sure it's pristine 
    FD_ZERO(&fds); 
    // Set the FD that we want to read 
    FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0 
    // select takes the last file descriptor value + 1 in the fdset to check, 
    // the fdset for reads, writes, and errors. We are only passing in reads. 
    // the last parameter is the timeout. select will return if an FD is ready or 
    // the timeout has occurred 
    select(STDIN_FILENO+1, &fds, NULL, NULL, &tv); 
    // return 0 if STDIN is not ready to be read. 
    return FD_ISSET(STDIN_FILENO, &fds); 
} 
+0

+1 अच्छा ब्लॉग पोस्ट। – Tom

0

कॉल alarm() या ualarm()read() कॉल करने से पहले। यह SIGALRM सिग्नल को प्रक्रिया में वितरित करने का कारण बनता है, पढ़ने(), को प्रदान करने में बाधा डालती है जिसे आपने ओ/एस को इंटरप्ट के बाद सिस्टम कॉल को पुनरारंभ करने के लिए नहीं बताया है। read() सामान्य रूप से लौटने पर अलार्म को रद्द करना सुनिश्चित करें।

+1

'SIGALRM 'के लिए डिफ़ॉल्ट हैंगरर प्रक्रिया को समाप्त करता है, इसलिए आपको सिग्नल हैंडलर इंस्टॉल करना होगा। और एक सीन ओएस पर, सिग्नल डिफ़ॉल्ट रूप से सिस्कोल को बाधित नहीं करते हैं, इसलिए आपको यह सुनिश्चित करने के लिए 'सिग्नल' के बजाय 'सिग्नेक्शन' का उपयोग करना होगा। –

6

चयन, चुनाव या किसी अन्य आईओ मल्टीप्लेक्सिंग सुविधा का उपयोग करें। वे सभी एक टाइमआउट तर्क लेते हैं। ध्यान दें कि अगर यह नियमित फाइल है तो यह काम नहीं करेगा, लेकिन अगर यह एक टर्मिनल/टीटीआई, सॉकेट, पाइप है तो यह होगा।

उदा।

fd_set selectset; 
struct timeval timeout = {10,0}; //timeout of 10 secs. 
int ret; 
FD_ZERO(&selectset); 
FD_SET(0,&selectset); 
ret = select(1,&selectset,NULL,NULL,&timeout); 
if(ret == 0) 
    //timeout 
else if(ret == -1) 
    //error 
else 
    // stdin has data, read it 
    // (we know stdin is readable, since we only asked for read events 
    //and stdin is the only fd in our select set. 
+0

उत्तर के लिए +1 जो सिग्नल पर निर्भर नहीं है और प्रक्रिया की वैश्विक स्थिति के साथ गड़बड़ कर रहा है, जो लाइब्रेरी कोड से उचित/स्वीकार्य नहीं हो सकता है। –

+0

ठीक है, यह एक नियमित फ़ाइल के लिए "काम" करेगा, क्योंकि यह हमेशा कहता है कि इससे पढ़ने से अवरुद्ध नहीं होगा, जो सच है (डेटा की आपूर्ति करने के लिए डिस्क या नेटवर्क फाइल सिस्टम की प्रतीक्षा करना "अवरोधन" के रूप में नहीं गिना जाता है) । – caf

+0

दाएं, इसे अवरुद्ध करने के रूप में नहीं माना जाता है, फिर भी यह काफी समय तक अवरुद्ध हो सकता है। – nos