【问题标题】:why only my first x forks make the job (gcc)为什么只有我的前 x 个叉子才能完成这项工作(gcc)
【发布时间】:2009-09-27 22:03:30
【问题描述】:

这是来自我的学习指南。从我的角度来看,这几乎完成了,但我不能让它按照我想要的方式工作。 练习是:

给定一个字符串叉 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();
    }


} 

这是我得到的输出

gabriel@GaboMac: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

所有回声都应该像前五个一样。

有什么想法吗?

【问题讨论】:

    标签: c gcc fork


    【解决方案1】:

    首先,这是一个糟糕的代码。你永远不应该在信号处理程序中做真正的工作。该程序的主循环位于信号处理程序中 - 不好!

    问题是您的子进程在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... */
        ...
    }
    

    【讨论】:

    • 是的!在阅读本文前几分钟,我想出了你所说的处理程序中的时间。不要在处理程序中执行操作我这样做是因为我虽然这是最好的方法,但您有任何链接可以阅读有关此约定的内容吗?谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-28
    • 1970-01-01
    • 1970-01-01
    • 2012-03-26
    • 1970-01-01
    相关资源
    最近更新 更多