2012-03-03 11 views
5

कोड सी संकेत हैंडलर में काम नहीं कर रहा पहला:Printf (कम से कम मामले) विचाराधीन

#include <stdio.h> 
#include <signal.h> 

int counter = 0; 

void react_to_signal(int n) { 
    fprintf(stderr, "Caught!\n"); 
    counter++; 
} 

int main(int argc, char** argv) { 

    signal(SIGINFO, react_to_signal); 

    while (1) { 
     printf("%d\n", counter); 
    } 

    return 0; 
} 

मैं कोड चलाने के लिए, यह एकदम सही ढंग से लूप होता है, एक और खोल में फिर 0. बाहर मुद्रण ..

kill -s SIGINFO <pid_of_my_process> 

सिग्नल वितरित किया गया है, c बढ़ी है .. लेकिन fprintf नहीं होता है।

ऐसा क्यों है? हैंडलर कोड किस पर्यावरण/संदर्भ में चलता है? मैं इस पर कहां पढ़ सकता हूं?

+0

'fflush (stderr)' – Saphrosit

+2

का उपयोग करके stderr को फ्लश करने का प्रयास करें printf() et.al का उपयोग न करें। सिग्नल हैंडलर के अंदर। वे सिग्नल सुरक्षित नहीं हैं (उदाहरण: मॉलोक() को कॉल कर सकते हैं, जो सिग्नल-सुरक्षित नहीं है) – wildplasser

+0

आश्चर्यजनक रूप से, मैंने शपथ ली थी कि मैंने पोस्ट करने से पहले 'fflush' के साथ एक संस्करण की कोशिश की थी। या तो कभी भी पुनः संकलित नहीं हुआ और भाग गया, या अनन्य पाश के साथ पैर में खुद को गोली मार दी, जिससे संदेश बंद हो गया। तो अनौपचारिक और गूंगा। – ntl0ve

उत्तर

14

संक्षेप में: आप संकेत हैंडलर भीतर सुरक्षित रूप से printf का उपयोग नहीं कर सकते

वहाँ संकेत हैंडलर आदमी पृष्ठ में एक list of authorized functionsAsync-संकेत सुरक्षित अनुभाग में, है। इसमें fprintf नहीं है।

ऐसा इसलिए है क्योंकि यह फ़ंक्शन पुनर्विक्रेता नहीं है, मुख्य रूप से क्योंकि यह मॉलोक और मुफ्त का उपयोग कर सकता है। विस्तृत विवरण के लिए this post देखें।

+0

ठीक है, अब सब स्पष्ट है। आपका बहुत बहुत धन्यवाद! – ntl0ve

1

प्रोग्राम से बाहर निकलने से पहले संदेश लिखने के लिए आपको stderr fflush की आवश्यकता हो सकती है।

+0

क्या यह एक नई लाइन तक पहुंचने पर स्वचालित रूप से 'printf' फ्लश नहीं करता है? –

+1

नहीं देखें https://stackoverflow.com/questions/5229096/does-printf-always-flush-the-buffer-on-encountering-a-newline –