2014-10-27 4 views
5

द्वारा बार-बार अनब्लॉक किया गया है, मैं एक प्रोग्राम लिख रहा हूं जो फ़ाइल से यूनिक्स कमांड की एक सूची लेता है और क्रमशः उन्हें निष्पादित करता है। सबकुछ क्रम में रखने के लिए, मेरे पास प्रत्येक कमांड प्रारंभ होना चाहिए और SIGUSR1 के लिए sigwait() के माध्यम से प्रतीक्षा करना होगा। जब प्रत्येक आदेश प्रारंभ होता है, तो प्रत्येक आदेश निष्पादित कर सकता है।sigwait() SIGUSR1

उपयोग: > program.c input.txt

हालांकि, ऐसा लगता है कि SIGUSR1 बार-बार कहा जाता है पूरी तरह से sigwait() आगे निकल गए। यहाँ क्या हो रहा है? मैंने कई अलग-अलग चीजों की कोशिश की है, लेकिन हाल ही में इसे this answer के बाद मॉडलिंग किया गया है। पुन: प्रयास करने के लिए, मैं चाहता हूं कि प्रारंभिकरण के तुरंत बाद संकेतों के लिए सिग्नल उठाया जाए। की कोशिश की sigaction() को signal() बदलते: मैं जब सभी आदेशों पूरी तरह से प्रारंभ कर रहे हैं

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


void on_sigusr1(int sig) 
{ 
// Note: Normally, it's not safe to call almost all library functions in a 
// signal handler, since the signal may have been received in a middle of a 
// call to that function. 
    printf("SIGUSR1 received!\n"); 
} 

int main(int arc, char* argv[]) 
{ 


    FILE *file; 
    file = fopen(argv[1] ,"r"); 

    int BUF_SIZE = 100; 

    char *token; 
    char buffer[BUF_SIZE]; 
    char programs[BUF_SIZE]; 
    char *commands[BUF_SIZE]; 

    int i = 0; 
    int counter = 1; 

    while (fgets(buffer, sizeof buffer, file) != NULL) 
    { 
     strcpy(programs, buffer); 

     int length = strlen(buffer)-1; 
     if (buffer[length] == '\n') 
     { 
      buffer[length] = '\0'; 
     } 

     i = 0; 
     token = strtok(buffer," "); 
     while(token != NULL) 
     { 
      commands[i++] = token; 
      token = strtok(NULL, " "); 
     } 
     commands[i] = 0; 

     pid_t pids[counter]; 


     // Set a signal handler for SIGUSR1 
     signal(SIGUSR1, &on_sigusr1); 

    // At program startup, SIGUSR1 is neither blocked nor pending, so raising it 
    // will call the signal handler 
     raise(SIGUSR1); 

    // Now let's block SIGUSR1 
     sigset_t sigset; 
     sigemptyset(&sigset); 
     sigaddset(&sigset, SIGUSR1); 
     sigprocmask(SIG_BLOCK, &sigset, NULL); 

    // SIGUSR1 is now blocked, raising it will not call the signal handler 
     printf("About to raise SIGUSR1\n"); 
     raise(SIGUSR1); 
     printf("After raising SIGUSR1\n"); 


     for(i = 0; i < counter; ++i) 
     { 
      pids[i] = fork(); 

      if(pids[i] > 0) 
      { 
       printf("Child process %d ready to execute command %s", getpid(), programs); 
       // SIGUSR1 is now blocked and pending -- this call to sigwait will return 
       // immediately 
       int sig; 
       int result = sigwait(&sigset, &sig); 
       if(result == 0) { 
        printf("Child process %d executing command %s", getpid(), programs); 
        execvp(commands[0], commands); 
       } 
      } 
     } 

     // All programs have been launched 
     for(i = 0; i < counter; ++i) 
     { 
      wait(&pids[i]); 
     } 

     // All programs are waiting to execute 
     for (i = 0; i < counter; ++i) 
     { 
     // SIGUSR1 is now no longer pending (but still blocked). Raise it again and 
     // unblock it 
      raise(SIGUSR1); 
      printf("About to unblock SIGUSR1\n"); 
      sigprocmask(SIG_UNBLOCK, &sigset, NULL); 
      printf("Unblocked SIGUSR1\n"); 
     } 
    } 

exit(0); 
fclose(file); 
return 0; 
} 

अद्यतन संकेत अनवरोधित करना चाहते हैं। कोई परिवर्तन नहीं होता है।

+0

"* ... SIGUSR1 बार-बार कहा जाता है *" एक संकेत नहीं कहा जाता है। कृपया आप वास्तव में क्या व्यक्त करना चाहते हैं? – alk

+1

'सिग्नल' के बजाय 'सिग्नेक्शन' का उपयोग करने का प्रयास करें। –

+0

@alk: मैं चाहता हूं कि प्रारंभिकरण के तुरंत बाद संकेतों के लिए संकेत उठाया जाए। मैं चाहता हूं कि सिग्नल को अनब्लॉक किया जाए जब सभी आदेश पूरी तरह से प्रारंभ हो जाएं। –

उत्तर

1

के बाद आपको यह पता लगाने के लिए कि क्या वह बच्चा एक बाल प्रक्रिया है, आपको सिग्वाइट पर कॉल करने पर विचार करना चाहिए।

तो शायद

int sig;

और

पूर्णांक परिणाम = sigwait (& sigset, & sig);

एक बयान के भीतर जो जांचता है कि क्या पिड == 0 है जो इंगित करेगा कि यह एक बच्चा है। अन्यथा आप एक माता-पिता की प्रक्रिया का इंतजार करेंगे।

यदि पिड 0 से अधिक है तो यह एक मूल प्रक्रिया आईडी है और यदि यह शून्य से कम है तो यह एक त्रुटि है।

फिर अपनी प्रक्रियाओं में से प्रत्येक प्रक्रिया के लिए आप इसे अनवरोधित करने के लिए मार (pid_array [i], SIGUSR1) को कॉल करेंगे।

+0

यह उदाहरण कुल गड़बड़ है .. बच्चे को फोर्किंग करना जो माता-पिता के कोड को निष्पादित करना शुरू कर देता है, जबकि माता-पिता बच्चे को कोड निष्पादित करते हैं .. इसे केवल शुरुआत पर क्रैश होना चाहिए। – Nazar

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