2009-09-27 2 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을받지 못할 것입니다.

그 이유는 자녀 프로세스가 첫 번째 신호를 처리 한 후 응답을 멈추는 이유입니다.

지금, 심각하게. 가서 최소한의 신호 처리로 다시 작성하십시오. 그것은 보통 이런 식으로 이루어집니다 ...

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

예! 몇 분 전에이 책을 읽으세요. 당신이 처리기에 대해 말한 것을 제가 생각한 것입니다. 그런 식으로 처리 한 처리기에서 작업을 수행하지 마십시오. 처리하는 데 가장 좋은 방법이기 때문에이 규칙을 읽으려는 링크가 있습니까? 고맙습니다 –

관련 문제