2009-09-27 75 views
0

這是我的學習指南。從我的角度來看,這幾乎已經完成,但我無法按照自己想要的方式工作。 練習是:爲什麼只有我的第一個x叉子做這份工作(gcc)

給定一個字符串叉X次併爲每個孩子打印一個字符,直到字符串完成。

這是代碼和編譯:

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <errno.h> 
#include <dirent.h> 
#include <string.h> 
#include <sys/wait.h> 
#include <fcntl.h> 



// SOME PROGRAM CONSTANTS 

#define CHILD_QUANTITY 5 
#define FIFO_FILE "/tmp/printer.fifo" 
#define STRING_TO_PRINT "hola mundo como estas!!!!" 
#define DELAY_TIME 2 // two seconds 

// SOME GLOBAL VARIABLES 
int fdfifo, next_printer = 0, next_char = 0; 
pid_t printers[CHILD_QUANTITY]; 



void process_call_printer(int sig) { 
    char char_to_print; 

    if (read(fdfifo, &char_to_print, sizeof(char)) == -1) { 
     perror(__FUNCTION__); 
    } 
     // print the char 
    printf("[%d] -> %c\n", getpid(), char_to_print); 


    // alert the parent process about it 
    kill(getppid(), SIGUSR2); 

    // just wait for another signal 
    while(1) { 
     pause(); 
    } 

} 

void process_call_hub(int sig) { 
    pid_t printer; 
    if (next_char < strlen(STRING_TO_PRINT)) { 
     if (write(fdfifo, &STRING_TO_PRINT[next_char], sizeof(char)) == -1) { 
      perror(__FUNCTION__); 
     } 
     alarm(DELAY_TIME); 

     if (next_printer >= CHILD_QUANTITY) { 
      next_printer = 0; 
     } 

     printer = printers[next_printer]; 
     next_printer++; 
     next_char++; 
     printf("sending char %c to the printer %d\n", STRING_TO_PRINT[next_char - 1], next_printer - 1); 
     kill(printer, SIGUSR1); 
    } 
    else { 
     kill(getpid(), SIGQUIT); 
    } 

} 

void process_callback(int sig) { 
// alarm(0); 
    printf("a callback function call\n"); 
// kill(getpid(), SIGALRM); 

// while(1) { 
//  pause(); 
// } 
} 

void system_shutdown(int sig) { 
    printf("SIGQUIT recived...terminating\n"); 

    if (unlink(FIFO_FILE) == -1) { 
     perror(__FUNCTION__); 
    } 

    close(fdfifo); 
} 


int main(void) { 
    pid_t pid; 

    int i; 

    if (mkfifo(FIFO_FILE, 0777) == -1) { 
     perror("pipe()"); 
     return -1; 
    } 

    fdfifo = open(FIFO_FILE, O_RDWR, 0777); 

    if (fdfifo == -1) { 
     perror("open()"); 
     return -2; 
    } 


    for (i = 0; i < CHILD_QUANTITY; i++) { 
     pid = fork(); 
     printers[i] = pid; 

     switch(pid) { 
      case -1: 
       perror("Error\n"); 
      break; 
      case 0: 
       // printer 
       signal(SIGUSR1, process_call_printer); 
       while(1) { 
        pause(); 
       } 

      break; 
      default: 
       // hub 
       // do nothing.. we will figure out later... 
      break; 
     } 

    } 

    signal(SIGALRM, process_call_hub); 
    signal(SIGQUIT, system_shutdown); 
    signal(SIGUSR2, process_callback); 

    alarm(DELAY_TIME); 

    while(1) { 
     pause(); 
    } 


} 

,這是輸出我

[email protected]:20090918$ ./threaded_printer 
sending char h to the printer 0 
[1397] -> h 
a callback function call 
sending char o to the printer 1 
[1398] -> o 
a callback function call 
sending char l to the printer 2 
[1399] -> l 
a callback function call 
sending char a to the printer 3 
[1400] -> a 
a callback function call 
sending char to the printer 4 
[1401] -> 
a callback function call 
sending char m to the printer 0 
sending char u to the printer 1 
sending char n to the printer 2 
sending char d to the printer 3 
sending char o to the printer 4 
sending char to the printer 0 
sending char c to the printer 1 
sending char o to the printer 2 
sending char m to the printer 3 
sending char o to the printer 4 
sending char to the printer 0 
sending char e to the printer 1 
sending char s to the printer 2 
sending char t to the printer 3 
sending char a to the printer 4 
sending char s to the printer 0 
sending char ! to the printer 1 
sending char ! to the printer 2 
sending char ! to the printer 3 
sending char ! to the printer 4 
SIGQUIT recived...terminating 

所有回聲應該像五個第一人。

有什麼想法?

回答

2

首先,這是可怕的代碼。你絕對不應該在信號處理器中做真正的工作。該程序在信號處理程序中有其主循環 - 不好!

問題是您的子進程在process_call_printer()信號處理程序中執行其工作,但該函數永不返回。它與

// just wait for another signal 
while(1) { 
    pause(); 
} 

嘛結束,這是怎麼回事,因爲當它被處理的信號被阻斷永遠等待的另一個信號。因此,您的孩子在完成處理第一個SIGUSR1之前不會再收到任何SIGUSR1 - 而且它從來不會這樣做。

這就是您的孩子處理完第一個信號後會停止響應的原因。

現在,認真。用最少的信號處理去改寫它。它通常是這樣做的...

int got_signal; 

void handler(int) { 
    got_signal = 1; 
} 


int main() { 
    ... 
    /* Wait for signal */ 
    got_signal = 0; 
    while(!got_signal) { 
     sleep(1); 
    } 
    /* Signal has arrived - do something... */ 
    ... 
} 
+0

是啊!在閱讀本文之前的幾分鐘,我想到了你在處理程序中所說的話。請不要在處理程序中執行操作,我是這樣做的,因爲儘管這是最好的方式,但是您有任何鏈接可以閱讀有關這些約定嗎?謝謝 – 2009-09-27 23:16:55

相關問題