簡體   English   中英

父子之間的溝通dup()

[英]communication between father and child dup()

我很難解決父親和孩子之間的溝通問題。 當我運行主程序時,似乎什么也沒發生。 我確實在網上搜索了解決方案,但到目前為止沒有任何幫助。 我知道我在這里發布了很多代碼,但是從我以前的帖子中得知了同樣的問題,人們已經送我一次又一次地讀那個人,但仍然有一些不對勁,我也不知道到底是什么。 我希望你們能幫助我

#include <stdio.h>
#include <stdlib.h> //for exit
#include <fcntl.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h> //for sleep(),execvp()
#include <ctype.h>
#include <fcntl.h>
#define IN 0
#define OUT 1
#define SIZE 81
#define EXEC "./child"

int main(int argc, char * argv[])
{
    int fd[2];
    int fdr;   // file descriptors
    int i;
    char result[3];
    pid_t pid;
    char charMatrix[SIZE] ={ 0 };
    int matrix[9][9]={0};
    if (argc < 2)
    {

        printf("No files added, abort program\n");
        exit(EXIT_FAILURE);
    }
    if (pipe(fd) == -1)
    {
        printf("Pipe Failed");
        return 1;
    }
    fdr = open(argv[1], O_RDONLY);   // open files
    if (fdr < 0)
    { //validation for error
        perror("failed to open input or output files");
        exit(EXIT_FAILURE); 
    }
    char c;

    charMatrix[81] = '\0';
    i=0;
    int j=0;
    while (read(fdr, &c, 1))          // read/write a single char
    {                                  // from/to the files
        if (c != ' ' && c != '\n')
        {
            charMatrix[i++]=c-'0';

        }


    }
    close(fdr);   // close the file
    int index=0;    //convert to matrix
    for (i = 0; i < 9; i++) { /* Iterate of each row */
            for (j = 0; j < 9; j++) { /* In each row, go over each col element  */
                matrix[i][j]=charMatrix[index++];
            }
        }
            for (i = 0; i < 9; i++) {//  Iterate of each row
            for (j = 0; j < 9; j++) {  //In each row, go over each col element
                printf("%d ", matrix[i][j]);//  Print each row element
            }
            printf("\n");//  Finish a row, start a new line
            }
    pid = fork();
    if (pid < 0)
    {
        fputs("error in fork", stderr);
        exit(EXIT_FAILURE);
    }
    //child
     if(pid == 0)
     {
                        close(fd[0]);
                close(STDOUT_FILENO);
                dup(fd[1]);
                        execl(EXEC, charMatrix, NULL);


     }
    //parent
     else{

        close(fd[1]);
        close(STDIN_FILENO);
        dup(fd[0]);
        read(fd[0], &result, sizeof(result));
        wait(NULL);

     }





    exit(EXIT_SUCCESS);
}

執行文件

#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

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

    int matrix[9][9];
    char charMatrix[81];
    char ans;
        int i, j;
        printf("got here");
        read(0,&charMatrix,sizeof(charMatrix));
    int index=0;    //convert to matrix
    for (i = 0; i < 9; i++) { /* Iterate of each row */
            for (j = 0; j < 9; j++) { /* In each row, go over each col element  */
                matrix[i][j]=charMatrix[index++];
            }
        }
    write(4, "a", sizeof(char));
    for (i = 0; i < 9; i++) { /* Iterate of each row */
        for (j = 0; j < 9; j++) { /* In each row, go over each col element  */
            printf("%d ", matrix[i][j]); /* Print each row element */
        }
        printf("\n"); /* Finish a row, start a new line */
    }
    exit(0);
}

在提出建議的解決方案之后,我嘗試添加另一個孩子,但仍然弄錯了。 這是代碼和一種解釋,我如何看待它

  dup2(pipe1[0], STDIN_FILENO); //makes the input( 0 in the stack) to the pipe1[0] which means point to its 
    close(pipe1[0]);
    close(pipe1[1]); //closing before pointes
    dup2(pipe2[1], STDOUT_FILENO); //makes the output (1 in the stack) to point pip1[1]
    close(pipe2[0]);
    close(pipe2[1]);//closing 
    execl(EXEC, EXEC, NULL);//exec

我曾嘗試用新煙斗與另一個孩子做同樣的事情,但沒有成功。 我將父親pipe1接到第二個孩子的pipe3的答案

// ------------------------------------------------ ------------------- //

#define SIZE 81
#define EXEC "./child"
#define EXEC2 "./child2"
int main(int argc, char *argv[])
{
    char charMatrix[SIZE] = { 0 };
    int matrix[9][9] = { 0 };
    char chilesStatus[3]={0};
    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s matrix file \n", argv[0]);
        exit(EXIT_FAILURE);
    }

    int fdr = open(argv[1], O_RDONLY);
    if (fdr < 0)
    {
        perror("failed to open input or output files");
        exit(EXIT_FAILURE);
    }

    char c;
    int k = 0;
    while (read(fdr, &c, 1) == 1 && k < (int)sizeof(charMatrix))
    {
        if (c != ' ' && c != '\n')
            charMatrix[k++] = c - '0';
    }

    close(fdr);

    int index = 0;
    for (int i = 0; i < 9; i++)
    {
        for (int j = 0; j < 9; j++)
            matrix[i][j] = charMatrix[index++];
    }

    printf("Input matrix:\n");
    for (int i = 0; i < 9; i++)
    {
        printf("P: ");
        for (int j = 0; j < 9; j++)
            printf(" %d", matrix[i][j]);
        printf("\n");
    }
    fflush(stdout);     // Making sure output is flushed even if it is going to a pipe

    int pipe1[2];
    int pipe2[2];
    int pipe3[2];
    int pipe4[2];

    if (pipe(pipe1) == -1 || pipe(pipe2) == -1 || pipe(pipe3) == -1) //pipe validation
    {
        perror("Pipe failed");
        exit(EXIT_FAILURE);
    }

    pid_t fChild = fork();
    if (fChild < 0)
    {
        perror("Fork failed");
        exit(EXIT_FAILURE);
    }

    if (fChild == 0)
    {
        dup2(pipe1[0], STDIN_FILENO);
        close(pipe1[0]);
        close(pipe1[1]);
        dup2(pipe2[1], STDOUT_FILENO);
        close(pipe2[0]);
        close(pipe2[1]);
        execl(EXEC, EXEC, NULL);
        int errnum = errno;
        fprintf(stderr, "Failed to execute '%s' (%d: %s)\n", EXEC, errnum, strerror(errnum));
        exit(EXIT_FAILURE);
    }

    else
    {
        pid_t sChild = fork();
        if(sChild==0)
        {
                dup2(pipe2[0], STDIN_FILENO);
                    close(pipe2[0]);
                    close(pipe2[1]);
                    dup2(pipe3[1], STDOUT_FILENO);
                    close(pipe3[0]);
                    close(pipe3[1]);
                    execl(EXEC2, EXEC2, NULL);
                    int errnum = errno;
                    fprintf(stderr, "Failed to execute '%s' (%d: %s)\n", EXEC, errnum, strerror(errnum));
                    exit(EXIT_FAILURE);
        }
        else
        {

        }
    close(pipe2[0]);
        close(pipe1[0]);
        if (write(pipe1[1], charMatrix, sizeof(charMatrix)) != sizeof(charMatrix))
        {
            perror("failed to write to child");
            exit(EXIT_FAILURE);
        }
    if (write(pipe1[2], charMatrix, sizeof(charMatrix)) != sizeof(charMatrix))
        {
            perror("failed to write to child");
            exit(EXIT_FAILURE);
        }
        close(pipe1[1]);
        close(pipe2[1]);
    close(pipe3[1]);
        char result[3];
        int nbytes = read(pipe2[0], &result, sizeof(result));
    int nbytes2 = read(pipe3[0], &result, sizeof(result));
        if (nbytes <= 0 ||nbytes2 <= 0) 
        {
            perror("Failed to read from pipe");
            exit(EXIT_FAILURE);
        }

        close(pipe2[0]);
    close(pipe3[0]);
        int corpse;
        int status;
        while ((corpse = wait(&status)) > 0)
            printf("Child %d exited with status 0x%.4X\n", corpse, status);

        printf("Received '%.*s' from child\n", nbytes, result);
    }

    return(EXIT_SUCCESS);
}

一個孩子的過程

這兩個源文件的主要修訂版parent.cchild.c

parent.c

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

#define SIZE 81
#define EXEC "./child"

int main(int argc, char *argv[])
{
    char charMatrix[SIZE] = { 0 };
    int matrix[9][9] = { 0 };

    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s matrixfile\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    int fdr = open(argv[1], O_RDONLY);
    if (fdr < 0)
    {
        perror("failed to open input or output files");
        exit(EXIT_FAILURE);
    }

    char c;
    int k = 0;
    while (read(fdr, &c, 1) == 1 && k < (int)sizeof(charMatrix))
    {
        if (c != ' ' && c != '\n')
            charMatrix[k++] = c - '0';
    }

    close(fdr);

    int index = 0;
    for (int i = 0; i < 9; i++)
    {
        for (int j = 0; j < 9; j++)
            matrix[i][j] = charMatrix[index++];
    }

    printf("Input matrix:\n");
    for (int i = 0; i < 9; i++)
    {
        printf("P: ");
        for (int j = 0; j < 9; j++)
            printf(" %d", matrix[i][j]);
        printf("\n");
    }
    fflush(stdout);     // Make sure output is flushed even it it is going to a pipe

    int pipe1[2];
    int pipe2[2];
    if (pipe(pipe1) == -1 || pipe(pipe2) == -1)
    {
        perror("Pipe failed");
        exit(EXIT_FAILURE);
    }

    pid_t pid = fork();
    if (pid < 0)
    {
        perror("Fork failed");
        exit(EXIT_FAILURE);
    }

    if (pid == 0)
    {
        dup2(pipe1[0], STDIN_FILENO);
        close(pipe1[0]);
        close(pipe1[1]);
        dup2(pipe2[1], STDOUT_FILENO);
        close(pipe2[0]);
        close(pipe2[1]);
        execl(EXEC, EXEC, NULL);
        int errnum = errno;
        fprintf(stderr, "Failed to execute '%s' (%d: %s)\n", EXEC, errnum, strerror(errnum));
        exit(EXIT_FAILURE);
    }

    else
    {
        close(pipe1[0]);
        if (write(pipe1[1], charMatrix, sizeof(charMatrix)) != sizeof(charMatrix))
        {
            perror("failed to write to child");
            exit(EXIT_FAILURE);
        }
        close(pipe1[1]);

        close(pipe2[1]);
        char result[3];
        int nbytes = read(pipe2[0], &result, sizeof(result));
        if (nbytes <= 0)
        {
            perror("Failed to read from pipe");
            exit(EXIT_FAILURE);
        }
        close(pipe2[0]);

        int corpse;
        int status;
        while ((corpse = wait(&status)) > 0)
            printf("Child %d exited with status 0x%.4X\n", corpse, status);

        printf("Received '%.*s' from child\n", nbytes, result);
    }

    return(EXIT_SUCCESS);
}

child.c

#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

int main(void)
{
    int matrix[9][9];
    char charMatrix[81];

    fprintf(stderr, "got here\n");
    int nbytes = read(STDIN_FILENO, charMatrix, sizeof(charMatrix));
    fprintf(stderr, "got %d bytes\n", nbytes);
    int index = 0;
    for (int i = 0; i < 9; i++)
    {
        for (int j = 0; j < 9; j++)
            matrix[i][j] = charMatrix[index++];
    }

    write(STDOUT_FILENO, "a", sizeof(char));
    fprintf(stderr, "Ack written to parent\n");

    fprintf(stderr, "Child matrix:\n");
    for (int i = 0; i < 9; i++)
    {
        fprintf(stderr, "C: ");
        for (int j = 0; j < 9; j++)
            fprintf(stderr, " %d", matrix[i][j]);
        fprintf(stderr, "\n");
    }

    return(0);
}

隨機矩陣

6 9 4 5 3 2 6 1 2
2 7 1 5 1 9 1 5 7
1 5 3 1 6 6 7 1 8
6 3 2 4 2 8 9 5 2
2 2 7 9 4 1 3 7 7
3 1 7 8 6 5 5 2 4
6 5 9 1 6 7 7 8 7
5 4 9 5 1 8 9 2 1
3 5 6 8 3 6 9 6 9

輸出量

$ ./parent random.matrix
Input matrix:
P:  6 9 4 5 3 2 6 1 2
P:  2 7 1 5 1 9 1 5 7
P:  1 5 3 1 6 6 7 1 8
P:  6 3 2 4 2 8 9 5 2
P:  2 2 7 9 4 1 3 7 7
P:  3 1 7 8 6 5 5 2 4
P:  6 5 9 1 6 7 7 8 7
P:  5 4 9 5 1 8 9 2 1
P:  3 5 6 8 3 6 9 6 9
got here
got 81 bytes
Ack written to parent
Child matrix:
C:  6 9 4 5 3 2 6 1 2
C:  2 7 1 5 1 9 1 5 7
C:  1 5 3 1 6 6 7 1 8
C:  6 3 2 4 2 8 9 5 2
C:  2 2 7 9 4 1 3 7 7
C:  3 1 7 8 6 5 5 2 4
C:  6 5 9 1 6 7 7 8 7
C:  5 4 9 5 1 8 9 2 1
C:  3 5 6 8 3 6 9 6 9
Child 9498 exited with status 0x0000
Received 'a' from child
$

兩個子進程

目前尚不清楚為什么要定義,但不要在修改后的代碼中使用pipe4 我認為這樣會更容易。 當您從1到2進程移動時,帶有數字后綴的命名約定變得令人討厭(但是下面的代碼仍然使用它)。 最好考慮數組。 我修改了子進程以發送更大的消息,並修改了父代碼以接收它們-它可以更好地識別正在發生的事情。 來自孩子的輸出可以被交錯。

我不清楚您如何設想管道的三重奏。 使用四個管道,管道1和2連接到子節點1。 管道3和4通往子代2。奇數管道將信息傳遞給子代。 偶數管道傳達孩子的信息。 有很多對close()的調用。

pipe47.c

/* SO 5609-3694 */
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>

#define SIZE 81
#define EXEC1 "./child2"
#define EXEC2 "./child2"

int main(int argc, char *argv[])
{
    char charMatrix[SIZE] = { 0 };
    int matrix[9][9] = { 0 };

    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s matrix file \n", argv[0]);
        exit(EXIT_FAILURE);
    }

    int fdr = open(argv[1], O_RDONLY);
    if (fdr < 0)
    {
        perror("failed to open input or output files");
        exit(EXIT_FAILURE);
    }

    char c;
    int k = 0;
    while (read(fdr, &c, 1) == 1 && k < (int)sizeof(charMatrix))
    {
        if (c != ' ' && c != '\n')
            charMatrix[k++] = c - '0';
    }

    close(fdr);

    int index = 0;
    for (int i = 0; i < 9; i++)
    {
        for (int j = 0; j < 9; j++)
            matrix[i][j] = charMatrix[index++];
    }

    printf("Input matrix:\n");
    for (int i = 0; i < 9; i++)
    {
        printf("P: ");
        for (int j = 0; j < 9; j++)
            printf(" %d", matrix[i][j]);
        printf("\n");
    }
    fflush(stdout);     // Making sure output is flushed even if it is going to a pipe

    int pipe1[2];
    int pipe2[2];
    int pipe3[2];
    int pipe4[2];

    if (pipe(pipe1) == -1 || pipe(pipe2) == -1 || pipe(pipe3) == -1 || pipe(pipe4) == -1) // pipe validation
    {
        perror("Pipe failed");
        exit(EXIT_FAILURE);
    }

    pid_t fChild = fork();
    if (fChild < 0)
    {
        perror("Fork failed (child 1)");
        exit(EXIT_FAILURE);
    }

    if (fChild == 0)
    {
        dup2(pipe1[0], STDIN_FILENO);
        dup2(pipe2[1], STDOUT_FILENO);
        close(pipe1[0]);
        close(pipe1[1]);
        close(pipe2[0]);
        close(pipe2[1]);
        close(pipe3[0]);
        close(pipe3[1]);
        close(pipe4[0]);
        close(pipe4[1]);
        execl(EXEC1, EXEC1, NULL);
        int errnum = errno;
        fprintf(stderr, "Failed to execute '%s' (1) (%d: %s)\n", EXEC1, errnum, strerror(errnum));
        exit(EXIT_FAILURE);
    }

    pid_t sChild = fork();
    if (sChild < 0)
    {
        perror("Fork failed (child 2)");
        exit(EXIT_FAILURE);
    }

    if (sChild == 0)
    {
        dup2(pipe3[0], STDIN_FILENO);
        dup2(pipe4[1], STDOUT_FILENO);
        close(pipe1[0]);
        close(pipe1[1]);
        close(pipe2[0]);
        close(pipe2[1]);
        close(pipe3[0]);
        close(pipe3[1]);
        close(pipe4[0]);
        close(pipe4[1]);
        execl(EXEC2, EXEC2, NULL);
        int errnum = errno;
        fprintf(stderr, "Failed to execute '%s' (2) (%d: %s)\n", EXEC2, errnum, strerror(errnum));
        exit(EXIT_FAILURE);
    }

    close(pipe1[0]);
    close(pipe2[1]);
    close(pipe3[0]);
    close(pipe4[1]);

    if (write(pipe1[1], charMatrix, sizeof(charMatrix)) != sizeof(charMatrix))
    {
        perror("failed to write to child 1");
        exit(EXIT_FAILURE);
    }
    close(pipe1[1]);

    if (write(pipe3[1], charMatrix, sizeof(charMatrix)) != sizeof(charMatrix))
    {
        perror("failed to write to child 2");
        exit(EXIT_FAILURE);
    }
    close(pipe3[1]);

    char result1[64];
    int nbytes1 = read(pipe2[0], &result1, sizeof(result1));
    close(pipe2[0]);
    if (nbytes1 <= 0)
    {
        perror("Failed to read from child 1");
        exit(EXIT_FAILURE);
    }

    char result2[64];
    int nbytes2 = read(pipe4[0], &result2, sizeof(result2));
    close(pipe4[0]);
    if (nbytes2 <= 0)
    {
        perror("Failed to read from child 2");
        exit(EXIT_FAILURE);
    }

    int corpse;
    int status;
    while ((corpse = wait(&status)) > 0)
        printf("Child %d exited with status 0x%.4X\n", corpse, status);

    printf("Received '%.*s' from child 1\n", nbytes1, result1);
    printf("Received '%.*s' from child 2\n", nbytes2, result2);

    return(EXIT_SUCCESS);
}

child2.c

/* SO 5609-3694 */
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

int main(void)
{
    int matrix[9][9];
    char charMatrix[81];
    int pid = getpid();

    fprintf(stderr, "PID %d: got here\n", pid);
    int nbytes = read(STDIN_FILENO, charMatrix, sizeof(charMatrix));
    fprintf(stderr, "PID %d: got %d bytes\n", pid, nbytes);
    int index = 0;
    for (int i = 0; i < 9; i++)
    {
        for (int j = 0; j < 9; j++)
            matrix[i][j] = charMatrix[index++];
    }

    //write(STDOUT_FILENO, "a", sizeof(char));
    printf("PID %d: message received", pid);
    fprintf(stderr, "PID %d: Ack written to parent\n", pid);

    fprintf(stderr, "PID %d: Child matrix:\n", pid);
    for (int i = 0; i < 9; i++)
    {
        fprintf(stderr, "PID %d: ", pid);
        for (int j = 0; j < 9; j++)
            fprintf(stderr, " %d", matrix[i][j]);
        fprintf(stderr, "\n");
    }

    return(0);
}

輸出量

請注意,兩個子項的輸出相互穿插。 可以設計一種機制來避免這種情況。

$ ./pipe47 random.matrix
Input matrix:
P:  6 9 4 5 3 2 6 1 2
P:  2 7 1 5 1 9 1 5 7
P:  1 5 3 1 6 6 7 1 8
P:  6 3 2 4 2 8 9 5 2
P:  2 2 7 9 4 1 3 7 7
P:  3 1 7 8 6 5 5 2 4
P:  6 5 9 1 6 7 7 8 7
P:  5 4 9 5 1 8 9 2 1
P:  3 5 6 8 3 6 9 6 9
PID 11903: got here
PID 11903: got 81 bytes
PID 11903: Ack written to parent
PID 11903: Child matrix:
PID 11903:  6 9 4 5 3 2 6 1 2
PID 11903:  2 7 1 5 1PID 11904: got here
 9 1 5 7
PID 11903:  1 5 3 1PID 11904: got 81 bytes
 6 6 7 1 8
PID 11903:  6 3 2PID 11904: Ack written to parent
 4PID 11904: Child matrix:
 2PID 11904:  8 6 9 9 5 4 2 5
 3PID 11903:  2 2 6 2 1 7 2 9 4 1
 3PID 11904:  7 2 7 7
 1PID 11903:  5 3 1 1 9 7 1 8 5 6 7 5
 5PID 11904:  2 1 4 5
 3PID 11903:  1 6 6 5 6 9 7 1 1 6 8 7
 7PID 11904:  8 6 7 3
 2PID 11903:  4 5 2 4 8 9 9 5 5 1 2 8
 9PID 11904:  2 2 1 2
 7PID 11903:  9 3 4 5 1 6 3 8 7 3 7 6
 9PID 11904:  6 3 9 1
 7 8 6 5 5 2 4
PID 11904:  6 5 9 1 6 7 7 8 7
PID 11904:  5 4 9 5 1 8 9 2 1
PID 11904:  3 5 6 8 3 6 9 6 9
Child 11903 exited with status 0x0000
Child 11904 exited with status 0x0000
Received 'PID 11903: message received' from child 1
Received 'PID 11904: message received' from child 2
$

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM