叉子+管道问题

发布于 2024-10-19 05:59:49 字数 3196 浏览 5 评论 0原文

我对一个简单的程序有疑问,我用叉子和管道制作了一个用于学习目的的程序。 我想要一个孩子向父母发送一些数据,然后这个(父母)再次将其发送给孩子。

结果是,父进程的行为就像管道是非阻塞的,而子进程的行为就像管道是阻塞的一样。但我没有使用任何代码来告诉管道根本不是阻塞的。

让我展示一下:

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

void WriteStr(char* inStr)
{
    write(1,inStr,strlen(inStr));
}

int main(void){

    char *cad1 = "Introdueix un valor:  ";
int bytesr = 0;
char valor[256];

//Un pipe serveix solament per una comunicació unidereccional, 
//si es necessari que pare i fill es comuniquin en amdos sentits, 
//s'hauran d'utilitzar dos pipes.

int pip_fill[2];    //pip_fp[0]: file descriptor de lectura
                //pip_fp[1]: file descriptor d'escriptura

int pip_pare[2];    //pip_pf[0]: file descriptor de lectura
                //pip_pf[1]: file descriptor d'escriptura
int pid, nbytes = 0;
char cad[256];
int num = 0;

if (pipe (pip_fill)<0){
    write (1,"Pipe error!!!!\n",15);
    exit (1);
}

if (pipe (pip_pare)<0){
    write (1,"Pipe error!!!!\n",15);
    exit (1);
}

fflushnou();

pid = fork();
switch (pid){
    case -1:    
            //Error
            write (2,"Tractar_Valor: Error!!!!\n",25);
            exit (-1);
    case 0:
            //Fill
            //printf("Fill: fp[0]:%d fp[1]:%d pf[0]:%d pf[1]:%d \n",pip_fp[0],pip_fp[1],pip_pf[0],pip_pf[1]);
            close(pip_fill[0]);
                close(pip_pare[1]);

            while(1){
                bytesr = read(0, valor, 256);

                valor[bytesr] = '\0';

                write(pip_fill[1],valor,strlen(valor)); //el fill escriu a la pipe la var valor

                WriteStr("Fill avans\n");
                nbytes = read(pip_pare[0],cad,strlen(cad)); //el fill llegeix de la pipe la var un cop ha estat tractada per el pare
                WriteStr("Fill despres\n");

                if (nbytes != 0){   //vol dir que hem llegit algo per la pipe pip_pf
                    write(1,cad,strlen(cad));   //pintem cad per pantalla
                }

                sleep(1);
            }
    default:
            //Pare
            close(pip_fill[1]);
            close(pip_pare[0]);
            close(0);

            while(1){   

                nbytes = read(pip_fill[0],valor,strlen(valor));//el pare llegeix de la pipe la var valor 
                //WriteStr("Pare despres\n");
                if (nbytes != 0){   //vol dir que hem llegit algo per la pipe pip_fp
                    //tractem la variable valor
                    num = atoi(valor);
                    num = num*2;

                    sprintf(cad,"Valor actual de la variable: %d \n\n",num);

                    write(1,cad,strlen(cad));

                    write(pip_pare[1],cad,strlen(cad)); //el pare escriu a la pipe la var tractada
                }

                sleep(1);
            }
}
return 0;
}

实际行为是 child 接受输入,然后卡住读取“pip_pare[0]”。同时,父进程一直在循环并从“pip_fill[0]”读取值为0。

所以,我对此有点困惑,为什么父进程正在读取和loopinf而不在“read”函数中阻塞? ?

有什么建议来修复它吗?

感谢您的帮助:)

洛伦斯

I have a problem with a simple program im making with fork and pipes for learning purpose.
I want a child that send some data to the parent and this (the parent) send it again to the child.

The result is that the parent acts like the pipe is non-blocking and the child acts if the pipe is blocking. But i didnt use any code to tell that the pipes are non-blocking at all.

Let me show it:

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

void WriteStr(char* inStr)
{
    write(1,inStr,strlen(inStr));
}

int main(void){

    char *cad1 = "Introdueix un valor:  ";
int bytesr = 0;
char valor[256];

//Un pipe serveix solament per una comunicació unidereccional, 
//si es necessari que pare i fill es comuniquin en amdos sentits, 
//s'hauran d'utilitzar dos pipes.

int pip_fill[2];    //pip_fp[0]: file descriptor de lectura
                //pip_fp[1]: file descriptor d'escriptura

int pip_pare[2];    //pip_pf[0]: file descriptor de lectura
                //pip_pf[1]: file descriptor d'escriptura
int pid, nbytes = 0;
char cad[256];
int num = 0;

if (pipe (pip_fill)<0){
    write (1,"Pipe error!!!!\n",15);
    exit (1);
}

if (pipe (pip_pare)<0){
    write (1,"Pipe error!!!!\n",15);
    exit (1);
}

fflushnou();

pid = fork();
switch (pid){
    case -1:    
            //Error
            write (2,"Tractar_Valor: Error!!!!\n",25);
            exit (-1);
    case 0:
            //Fill
            //printf("Fill: fp[0]:%d fp[1]:%d pf[0]:%d pf[1]:%d \n",pip_fp[0],pip_fp[1],pip_pf[0],pip_pf[1]);
            close(pip_fill[0]);
                close(pip_pare[1]);

            while(1){
                bytesr = read(0, valor, 256);

                valor[bytesr] = '\0';

                write(pip_fill[1],valor,strlen(valor)); //el fill escriu a la pipe la var valor

                WriteStr("Fill avans\n");
                nbytes = read(pip_pare[0],cad,strlen(cad)); //el fill llegeix de la pipe la var un cop ha estat tractada per el pare
                WriteStr("Fill despres\n");

                if (nbytes != 0){   //vol dir que hem llegit algo per la pipe pip_pf
                    write(1,cad,strlen(cad));   //pintem cad per pantalla
                }

                sleep(1);
            }
    default:
            //Pare
            close(pip_fill[1]);
            close(pip_pare[0]);
            close(0);

            while(1){   

                nbytes = read(pip_fill[0],valor,strlen(valor));//el pare llegeix de la pipe la var valor 
                //WriteStr("Pare despres\n");
                if (nbytes != 0){   //vol dir que hem llegit algo per la pipe pip_fp
                    //tractem la variable valor
                    num = atoi(valor);
                    num = num*2;

                    sprintf(cad,"Valor actual de la variable: %d \n\n",num);

                    write(1,cad,strlen(cad));

                    write(pip_pare[1],cad,strlen(cad)); //el pare escriu a la pipe la var tractada
                }

                sleep(1);
            }
}
return 0;
}

The actual behaviour is that child accepts input, and then stucks reading 'pip_pare[0]'. At the same time, parent process is looping and reading all the time from 'pip_fill[0]' a value of 0.

So, i am little confused about that, why parent is reading and loopinf without bloking in the 'read' function ??

Any suggestion to fix it ?

Thanks for the help :)

LLORENS

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

假装爱人 2024-10-26 05:59:49
nbytes = read(pip_pare[0],cad,strlen(cad));

我想你可能指的是 sizeof(cad)

write(1,cad,strlen(cad));

这里是 nbytes。

nbytes = read(pip_fill[0],valor,strlen(valor));

与此类似,但这个版本中有一个隐藏的陷阱,我将把它留作练习!

nbytes = read(pip_pare[0],cad,strlen(cad));

I think you probably meant sizeof(cad) here.

write(1,cad,strlen(cad));

And nbytes here.

nbytes = read(pip_fill[0],valor,strlen(valor));

And this along similar lines, but there's a hidden trap in this version which I shall leave as an exercise!

心安伴我暖 2024-10-26 05:59:49

发送可变长度数据时,最好先发送长度(以固定长度整数形式),以便接收者知道要请求多少数据。

When sending variable length data, it's a good idea to send the length first (in a fixed-length integer) so that the recipient knows how much data to request.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文