简体   繁体   English

C语言中与管道的双向处理

[英]Two way processes communication with pipes in C

I'm trying to make a program in c that forks a child and has two way communication using two separate pipes. 我正在尝试用c编写一个程序,该程序派生一个孩子,并使用两个单独的管道进行双向通信。

Summarizing; 总结;

  1. The father writes into pipe1 父亲写信给pipe1
  2. The child reads from pipe1 and make the calculations 孩子从pipe1读取并进行计算
  3. The child writes the answer in pipe2 孩子在pipe2中写答案
  4. The father reads the information from pipe2 父亲从pipe2读取信息

It is all going well till step 3, if I comment the code from point 4 then it all works and I even check for the write to pipe2 and it seems to work, but when I try to read from pipe2 in the father code it hangs and does not even executes the child calculations, step 2 and 3. please help me. 一切顺利,直到第3步,如果我注释了第4点的代码,则一切正常,我什至检查了对pipe2的写入,而且似乎正常,但是当我尝试从父代代码中的pipe2读取时,它挂起了并且甚至不执行子级计算(第2步和第3步)。请帮助我。 this is my code so far. 到目前为止,这是我的代码。

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

pid_t pid;
pid_t* trabajadores;

int nHijos = 1;

trabajadores = (pid_t*)malloc(sizeof(pid_t) * nHijos);

int** aHijos;
int links = 0;

// Matriz de pipes
aHijos = (int **) malloc(sizeof(int *) * nHijos);
for (i = 0; i < nHijos; i++) {
    aHijos[i] = (int *) malloc(sizeof(int)*2);
}

int alPadre[2];
pipe(alPadre);

// Se crea el pool de procesos
for (i = 0; i < nHijos; i++) {

    pipe(aHijos[i]);
    pid = fork();

    if (pid == 0) {

        int j;
        FILE* salidaHijo;
        FILE* entradaHijo;
        char buffer2[1024];
        close(alPadre [0]);
        for (j = 0; j<i; j++) {
            close(aHijos[j][0]);
            close(aHijos[j][1]);
        }
        close(aHijos[i][1]);

        entradaHijo = fdopen(aHijos[i][0], "r");


        // STEP 2
        while ( !feof (entradaHijo) &&  fgets (buffer2, sizeof (buffer2), entradaHijo) != NULL) {
            buffer2[strcspn(buffer2, "\n")] = 0;
        }

        char* resultado;


        /* CALCULATIONS */





// STEP 3
        salidaHijo = fdopen(alPadre[1], "w");
        printf("%i\n", fprintf(salidaHijo, "%s\n", resultado));
        fflush (salidaHijo);

        exit(0);

    } else {
        trabajadores[i] = 0;
        close(alPadre[1]);
        close(aHijos[i][0]);


        // STEP 1
        FILE** salidaPadre;
        salidaPadre = (FILE**)malloc(sizeof(FILE*) * nHijos);
        for (i = 0; i < nHijos; i++) {
            salidaPadre[i] = fdopen(aHijos[i][1], "w");
        }
        fprintf(salidaPadre[j], "%s\n", DesencolarT(trabajos));
        trabajadores[j] = 1;


        sleep(5);


        // STEP 4
        char buffer[1024];
        entradaPadre = fdopen(alPadre[0], "r");
        read(alPadre[0], buffer, sizeof(buffer));
        while ( !feof (entradaPadre) &&  fgets (buffer, sizeof (buffer), entradaPadre) != NULL) {
            printf("%s\n", buffer);

        }
    }
}
return 0; 
}

that wont compile it is just a pasted part of my code, here is the output from strace -ff -o test.log ./myProg for the two processes. 不会编译的代码只是我代码的粘贴部分,这是strace -ff -o test.log ./myProg的两个过程的输出。

getdents(4, /* 0 entries */, 32768)     = 0
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7761000
write(1, ". 160\n", 6)                  = 6
fcntl64(6, F_GETFL)                     = 0x1 (flags O_WRONLY)
fstat64(6, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7760000
_llseek(6, 0, 0xbfb8895c, SEEK_CUR)     = -1 ESPIPE (Illegal seek)
read(3, 0xbfb89738, 1024)               = ? ERESTARTSYS (To be restarted)
--- SIGINT (Interrupt) @ 0 (0) ---
+++ killed by SIGINT +++

AND

close(3)                                = 0
close(6)                                = 0
fcntl64(5, F_GETFL)                     = 0 (flags O_RDONLY)
fstat64(5, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7761000
_llseek(5, 0, 0xbfb8895c, SEEK_CUR)     = -1 ESPIPE (Illegal seek)
read(5, 0xb7761000, 4096)               = ? ERESTARTSYS (To be restarted)
--- SIGINT (Interrupt) @ 0 (0) ---

Thank you, sorry for the spanish the long post and the horrible formatting. 谢谢,对于西班牙语的冗长篇幅和可怕的格式深表歉意。


Using fflush() after step 1 and 3 I got to a point in where if I close pipe1() after step 1 everything works, the problem is that I need to keep writing to that child in the future so I can't close it. 在第1步和第3步之后使用fflush(),我得出的结论是,如果在第1步后关闭pipe1(),一切正常,问题是我将来需要继续写那个孩子,以致我无法关闭它。

In your parent, you don't want to close the write side of the pipe to the parent close(alPadre[1]); 在您的父级中,您不想关闭到父级close(alPadre[1]);的管道的写侧close(alPadre[1]); because then your subsequent children won't be able to talk to the parent using that pipe. 因为这样您以后的孩子将无法使用该管道与父母交谈。

Indeed, your subsequent calls to close(alPadre[1]); 实际上,您随后对close(alPadre[1]);调用close(alPadre[1]); in later loop iterations may unintentionally be closing other "random" file descriptors in the parent, as it will close whatever file descriptor number alPadre[1] happens to be at that time. 在以后的循环中,迭代可能会无意中关闭了父对象中的其他“随机”文件描述符,因为它将关闭alPadre[1]恰好是文件描述符编号alPadre[1]任何东西。 After you close any file descriptor you likely want to set that variable's value to -1 so that no further calls using that variable will have any effect. 关闭任何文件描述符之后,您可能希望将该变量的值设置为-1,以便使用该变量的进一步调用不会产生任何影响。

As another example, in your child process you call close(aHijos[j][0]); 再举一个例子,在您的子进程中,您调用close(aHijos[j][0]); for all j < i. 对于所有j <i。 Here again, most of these file descriptors were previously closed by the parent before the fork, so you are again "randomly" closing whatever file descriptor numbers happen to be at aHijos[j][0] for all j < i. 同样,大多数这些文件描述符之前都是在派生之前由父级关闭的,因此对于所有j <i,您都再次“随机”关闭aHijos[j][0]处的任何文件描述符编号。

Also, your parent eventually needs to close the write side of the pipe it uses to talk to each child, or the child will wait forever for more input in its input loop. 同样,您的父级最终需要关闭用于与每个孩子交谈的管道的写端,否则该孩子将永远等待其输入循环中的更多输入。 That is likely why your parent hangs at step #4, because your child is hanged at step #2 waiting for an EOF on the pipe from the parent. 这可能是您的父母在步骤#4处挂起的原因,因为您的孩子在步骤#2处被挂起,等待来自父母的管道上的EOF。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 管道双向通信 - Two-way communication with pipes 在Linux上使用C管道中的2个管道进行双向父子通信 - Two-Way Parent Child Communication Using 2 Pipes in C on Linux 如何使用涉及多次读写的管道在子进程和父进程之间实现双向通信 - How to implement two way communication between child and parent processes using pipes which involves multiple read and writes 使用两个单向管道的双向通讯 - two way communication using two unidirectional pipes 在C中创建管道用于多个进程之间的进程间通信 - Creating pipes in C for inter process communication between multiple processes 需要在Linux上具有能够在c中进行双向通信的非阻塞命名管道 - Need to have non-blocking named pipes capable of two way communication in c on Linux c-使用管道连续在两个子进程之间进行通信 - c - continously communicate between two child processes using pipes 在 C 中使用两个管道读取后无法退出循环(进程) - Unable to exit loop after reading using two pipes in C (processes) 使用C中的管道在父子之间创建双向通讯 - Create 2-way communication between parent and child using pipes in C 通过c中的半双工管道,父进程和2个子进程之间的通信出现问题 - problems with communication between parent and 2 child processes via half-duplex pipes in c
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM