2009-11-23 19 views
24
#include <stdio.h> 
#include <signal.h> 


void ALARMhandler(int sig) 
{ 
    signal(SIGALRM, SIG_IGN);   /* ignore this signal  */ 
    printf("Hello"); 
    signal(SIGALRM, ALARMhandler);  /* reinstall the handler */ 
} 

int main(int argc, char *argv[]) 
{ 
    alarm(2);      /* set alarm clock   */ 
    while (1) 
    ; 
    printf("All done"); 
} 

मैं इस कार्यक्रम 2 सेकंड के बाद प्रिंट "हैलो" करने की उम्मीद है, लेकिन बजाय उत्पादन होता है "zsh: अलार्म ./a.out"सरल सिग्नल - सी प्रोग्रामिंग और अलार्म समारोह

किसी भी विचार क्या है चल रहा?

उत्तर

31

आप प्रारंभ में अलार्म हैंडलर सेट करना भूल रहे हैं। main() के शुरू होने से बदले की तरह:

int main(int argc, char *argv[]) 
{ 
    signal(SIGALRM, ALARMhandler); 
    ... 

इसके अलावा, संकेत हैंडलर शायद कुछ भी नहीं प्रिंट होगा। ऐसा इसलिए है क्योंकि सी लाइब्रेरी तब तक आउटपुट कैश करता है जब तक यह लाइन का अंत नहीं देखता। तो:

void ALARMhandler(int sig) 
{ 
    signal(SIGALRM, SIG_IGN);   /* ignore this signal  */ 
    printf("Hello\n"); 
    signal(SIGALRM, ALARMhandler);  /* reinstall the handler */ 
} 

वास्तविक दुनिया के कार्यक्रम के लिए, सिग्नल हैंडलर से प्रिंटिंग बहुत सुरक्षित नहीं है। सिग्नल हैंडलर जितना छोटा हो उतना करना चाहिए, अधिमानतः केवल यहां या वहां ध्वज सेट करना चाहिए। और ध्वज घोषित किया जाना चाहिए volatile

+22

वास्तविक विश्व उदाहरण: मैंने एक बार उस सिस्टम पर काम किया जो बैक एंड के रूप में एक्सेस डेटाबेस का उपयोग करता था, और कुछ परिस्थितियों में सिग्नल हैंडलर में 'printf()' कॉल stdout की बजाय .mdb फ़ाइल को लिखता था, मरम्मत से परे डेटाबेस को खो देता था । अच्छे कार्यक्रम के लिए –

5

आप पहले सिग्नल हैंडलर इंस्टॉल नहीं कर रहे हैं।
आपको सिस्टम को यह बताना होगा कि आप वास्तव में इसे प्राप्त करने से पहले सिग्नल को संभालना चाहते हैं, इसलिए सिग्नल आने से पहले आपको मुख्य से signal() पर कॉल करने की आवश्यकता है।

int main(int argc, char *argv[]) 
{ 
    signal(SIGALRM, ALARMhandler);  /* install the handler */ 
    alarm(2);      /* set alarm clock   */ 
    while (1); 
} 
9

आप अपने main फ़ंक्शन में हैंडलर सेट नहीं कर रहे हैं।

alarm(2) करने से पहले, में signal(SIGALRM, ALARMhandler); डालें।

यह तब काम करना चाहिए।

ध्यान दें कि आपका "ऑल हो गया" कभी मुद्रित नहीं होगा, क्योंकि आप सिग्नल प्रोसेसर चलाने के बाद थोड़ी देर (1) लूप में रहेंगे। यदि आप लूप को तोड़ना चाहते हैं, तो आपको एक झंडा होना होगा जो सिग्नल हैंडलर बदलता है।

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

/* number of times the handle will run: */ 
volatile int breakflag = 3; 

void handle(int sig) { 
    printf("Hello\n"); 
    --breakflag; 
    alarm(1); 
} 

int main() { 
    signal(SIGALRM, handle); 
    alarm(1); 
    while(breakflag) { sleep(1); } 
    printf("done\n"); 
    return 0; 
} 
+4

+1। मुझे लगता है कि आपको सिग्नल हैंडलर में 'अलार्म (2)' कॉल करना होगा: आम तौर पर एक 'अलार्म()' कॉल केवल एक एकल 'SIGALRM' – Andomar

+0

उत्पन्न करता है बेशक, आप सही हैं। मैंने स्पष्ट रूप से इस कोड का परीक्षण नहीं किया है, और थोड़ी देर में इस तरह से संकेतों का उपयोग नहीं किया है (विशेष रूप से, वे इस तरह से उपयोग करने के लिए थ्रेडेड वातावरण में बेकार हैं)। – McPherrinM

+0

ब्रेकफ्लैग चर के लिए अस्थिर भंडारण वर्ग देने की क्या आवश्यकता है? – sujin

4

एंडोमर कठोर है। मैं इस परीक्षण करने और, संस्करण 1 प्रिंट (हर दूसरे):

Hi... 
Hi... 
Hi... 
Hi... 
BYE 
Hi... 
... 

संस्करण 2 प्रिंट (हर पांच सेकंड):

Hi...Hi...Hi...Hi...BYE 
Hi...Hi...Hi...Hi...BYE 
... 

तो कोड है:

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

# define T 5 

int flag = T; 

void sigalrm_handler(int); 

int main(void) 
{ 
    signal(SIGALRM, sigalrm_handler); 
    alarm(1);       
    while (1); 
} 

void sigalrm_handler(int sig) 
{ 
    if(--flag){ 
     printf("Hi...\n"); /*version 1*/ 
     /*printf("Hi...");*/ /*version 2*/ 
    }else{ 
     printf("BYE\n"); 
     flag=T;  
    } 
    alarm(1); 
} 
+0

पूर्ण और कार्यशील कोड के लिए धन्यवाद। मैंने इसे अपने मौजूदा प्रोग्राम के मुख्य {} के शीर्ष पर चिपकाया और इसे निकाल दिया। – user2548100

संबंधित मुद्दे