子进程通过管道发送一个号码,然后等待

时间:2017-03-30 14:34:15

标签: c pipe sleep

我尝试生成与管道连接的两个子进程。 孩子1应该通过管道向孩子2发送一个号码,孩子2应该打印它。我设法做到了这一点,但是当我尝试在循环中执行此操作时,如果孩子1在发送另一个号码之前每次等待1秒,则它不会发送任何内容。
我做错了什么?

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

int main(int argc, char *argv[]) {
    int fd[2];
    pipe(fd);
    pid_t pid1 = fork();
    if (pid1) {
        pid_t pid2 = fork();
        if (pid2) { //parent
            // do stuff as parent
        } else { //child 2
            close(fd[1]);
            char stringNumberReceived[10];
            while (1) {
                read(fd[0], stringNumberReceived, sizeof (stringNumberReceived));
                printf("number received: %s\n", stringNumberReceived);
            }
        }
    } else {//child 1
        close(fd[0]);
        int num;
        char stringnumber [10];
        while (1) {
            num = rand();
            snprintf(stringnumber, 10, "%d", num);
            printf("attempting to sent: %s\n", stringnumber);
            write(fd[1], stringnumber, strlen(stringnumber) + 1);
            Sleep(1000);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

这是您的代码的温和修改版本:

val modelOne = request.body.extractOpt[ModelOne]

val modelTwo = myService.buildModelTwoResponse(modelOne)

改变了什么?各种事情。您可以忽略大括号放置的变化;这纯粹是化妆品。

  1. 实施了父代码。
  2. 父级报告子进程ID。
  3. 父关闭管道 - 既不是读也不是写作。
  4. 父母等待孩子死亡,报告他们的状态。
  5. Child记录它读取的字节数,并确保它不会打印出来。
  6. 当它在管道上出现错误或EOF(读取0个字节)时退出循环并报告。
  7. 其他孩子在退出前会执行固定数量的周期(如图所示20)。
  8. 如果随机数生成器生成10位以上的数字,则可能会出现数组边界问题。我得到的最大长度是9,这是安全的。
  9. 生成孩子可以/应该在完成后报告。
  10. 在更改中,我怀疑关闭父管道可能是关键管道。

    示例输出(在Unix机器上):

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    
    enum { MAX_COUNT = 20 };
    
    int main(void)
    {
        int fd[2];
        pipe(fd);
        pid_t pid1 = fork();
        if (pid1)
        {
            pid_t pid2 = fork();
            if (pid2)   // parent
            {
                printf("Child 1: %d; child 2: %d\n", (int)pid1, (int)pid2);
                close(fd[0]);   // Let the child detect EOF!
                close(fd[1]);   // Let the child detect EOF!
                int corpse;
                int status;
                while ((corpse = wait(&status)) > 0)
                    printf("PID %d exited with status 0x%.4X\n", corpse, status);
            }
            else     // child 2
            {
                close(fd[1]);
                char stringNumberReceived[10];
                int nbytes;
                while ((nbytes = read(fd[0], stringNumberReceived, sizeof(stringNumberReceived))) > 0)
                    printf("number received: %.*s\n", nbytes, stringNumberReceived);
                printf("Child 2: EOF or ERR\n");
            }
        }
        else    // child 1
        {
            close(fd[0]);
            int num;
            char stringnumber[10];
            for (int counter = 0; counter < MAX_COUNT; counter++)
            {
                num = rand();
                snprintf(stringnumber, sizeof(stringnumber), "%d", num);
                printf("attempting to send: [%s] (len %zu)\n", stringnumber, strlen(stringnumber));
                write(fd[1], stringnumber, strlen(stringnumber) + 1);
                sleep(1);
            }
        }
        return 0;
    }