2012-11-07 62 views
1

我搜查了无法找到,所以我终于来求助了。 我的任务涉及(在RedHat Linux上运行的C语言中)创建两个子进程,每个子进程都将任意数量的迭代字符写入管道。该管道与创建它们的父进程共享。父母从管道读取,而孩子仍然有字符写入。一旦孩子退出并且管道是空的,父母(主)就可以终止。2个孩子写信给管道,家长从管道中读取C

这是我写的代码逻辑的一个很快的&脏例子。

main() 
{ 
     //create pipe 

     fork(); //childA 
     //writes to pipe 

     fork(); //childB 
     //writes to pipe 

     //parent reading 
     while(condition) { 
      //read from pipe + print chars to terminal 
     } 
} 

现在,我的问题是关于while循环的条件。 我需要阅读时,由于一个完整的管道阻止孩子写作,但我无法弄清楚什么样的条件会允许我这样做。任何帮助将是绝对惊人的。

+0

你应该总是阅读:这是摆脱“满管”状态的唯一方法。一旦最后一个孩子关闭管道,read将返回-1。 – wildplasser

+0

@wildplasser'read'在文件结束时返回0,错误时返回-1;所以当最后一个孩子关闭管道并且没有数据需要读取时它将返回0。 'fread'返回一个小于你请求的对象数(或0)的值,并且你需要使用'feof'和'ferror'来确定你是否有文件结尾或错误。 –

回答

0

阅读时是否要求管道满管?或者,是否仅仅是一个要求,即使其中一个管道已满,孩子在写作时被阻止,你还是继续读两个孩子?

我不知道任何标准的方式来如果管道满了高。您可以尝试使用ioctl来确定需要在管道上读取多少数据,然后将其与PIPE_BUF进行比较,但如果管道中的数据少于PIPE_BUF,但该子数据库正在执行写操作,则可能无法正常工作那会超过PIPE_BUF;该呼叫可能会阻塞而不填满管道。我不会依赖这种技术工作。

从两个文件描述符(不管哪一个已准备好)读取的通常方法是使用select系统调用。这允许您等待一个或另一个文件描述符具有可用数据。这意味着父进程不会阻止尝试从一个没有任何可用数据的孩子读取数据,而另一个孩子因为缓冲区已满而被阻塞。

编辑:重新读你的问题后,它听起来像实际上只有一个管道,这两个孩子正在写信给。那是对的吗?再次,问题出现在你是否需要等到孩子们被阻止。如果家长只是从管道读取数据,它将阻塞,直到其中一个孩子写入管道;你不需要做任何特别的事情。

如果您的任务需要您等待,直到管道实际上已满,我会有兴趣看到确切的措辞,因为我不知道为什么要这样做。

编辑2:在回答你的问题在注释:

  1. 确实为我的父进程的代码需要遵循的代码在程序中我的两个子进程?

    不,没有关于父或子进程的代码顺序的要求。为了区分父代码和子代码运行的代码,您需要检查返回值fork()。如果返回值为0,那么您处于子进程中。如果不是,你就在父母身边;如果返回值是-1,那么出现错误,如果它是正数,则它是子进程的PID。

    所以,你可以写这样的代码:

    int pid = fork(); 
    if (pid) { 
        // in the parent, check if pid is -1 for errors 
    } else { 
        // in the child 
    } 
    

    或者:

    int pid = fork(); 
    if (pid == 0) { 
        // in the child, do whatever you need to do and... 
        exit(0); 
    } 
    
    // in the parent; since the child calls exit() above, control will never 
    // reach here in the child. Or you could do an execl() in the child, which 
    // replaces the current program with another one, so again, control will 
    // never reach here within the child process. 
    
  2. 我怎能从管道读取,直到两个孩子终止,管道是空?

    只要继续读书,直到,直到所有进程都关闭了管道的写入结束read回报在管道的读端0 read将不会返回0,并且所有的数据已读出的管道。如果某些东西仍然打开,但管道中没有数据,则read将阻塞,直到数据写入管道。

    一个问题是要记住在尝试read之前关闭父进程中管道的写入结束;否则,当父母在孩子完成后试图执行read时,它将阻止等待它关闭自己的管道。

+0

事实上,只有一条管道,这两个孩子正在写信给父母,并正在阅读。 好吧,分配状态的要求,父母从管道读取每次读取100个字符,然后将所述字符打印到终端。这样做直到每个孩子已经完成其每个迭代(childA = 900次迭代,childB = 260次迭代)。 我想我不必等到孩子们被阻塞,但是我确实需要在每次读取时从管道读取100个字符。 – user1807614

+0

我想我的主要问题是: 1.我的父进程的代码是否需要遵循程序内我的两个子进程的代码? 2.我怎样才能继续阅读管道,直到两个孩子终止并且管道是空的? – user1807614

+0

@ user1807614我在回答中解答了您的问题 –