热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:当read()阻塞时如何退出while循环

篇首语:本文由编程笔记#小编为大家整理,主要介绍了当read()阻塞时如何退出while循环相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了当read()阻塞时如何退出while循环相关的知识,希望对你有一定的参考价值。



在大学给出的问题中,我们必须从父进程(P1)到其子P2的pipe,然后P2必须管道到P1的另一个孩子,另一个孩子是P3。 P2和P3都用c编写并制成可执行文件。然后他们将通过P1中的子进程进行qazxswwied。

P1将数字1到10000写入exec,P2通过其stdout读取它们,删除可被2整除的数字,并将结果写入其stdin。 P3通过其stdout读取这些数字,过滤掉可被3整除的结果,并将所有内容写入文件。

我已经成功实现了一切,但我的孩子流程并没有结束。我相信,其原因是我使用以下方法来读取每个子进程中的输入:

stdin

根据我的理解,这里的问题是当while(n=read(0, &i, sizeof(i))>0)
没有得到任何字节时会阻塞。由于P1使用以下方法写入10000个数字:

read

儿童进程都没有任何理由相信没有更多的数据可以实现。因此,每个for(i=1; i<=10000; i++){
write(1, &i, sizeof(i));
}
只是阻止等待一个永远不会到来的字节。

任何人都可以建议一种方法来克服这个障碍吗?

每个过程的代码如下:

家长:

read

P2(包括除外)

#include
#include
#include
#include
#include
#include
#include
#include
#include
int main()
{
// pipe to send input string from parent
// Child prints to file
int fd1[2]; // Used to store two ends of first pipe
int fd2[2]; // Used to store two ends of second pipe
//variables
int n, i, status1, status2;
char *args1[]={"./Div2",NULL};
char *args2[]={"./Div3",NULL};
//child process ids
pid_t pid1, pid2;
//open pipe 1
if (pipe(fd1)==-1)
{
fprintf(stderr, "Pipe 1 Failed" );
return 1;
}
//open pipe 2
if (pipe(fd2)==-1)
{
fprintf(stderr, "Pipe 2 Failed" );
return 1;
}
//create child 1
pid1 = fork();
if(pid1<0){
printf("Error creating child1
");
return(1);
}
if(pid1==0){ //child1
if(close(fd1[1])<0){ //child does not write to pipe 1
error();
}
if(close(fd2[0])<0){ //child does not read from pipe 2
error();
}
dup2(fd1[0], 0); //redirect stdin
dup2(fd2[1], 1); //redirect stdout
execvp(args1[0],args1);
if(close(fd1[0])<0){ //close used pipe
error();
}
if(close(fd2[0])<0){ //close used pipe
error();
}
exit(0);
}
pid2=fork();
if(pid2<0){
printf("Error creating child2
");
return(1);
}
if(pid2==0){ //child2
if(close(fd1[0])<0){ //child does not use pipe 1
error();
}
if(close(fd1[1])<0){
error();
}
if(close(fd2[1])<0){ //child does not write to pipe 2
error();
}
dup2(fd2[0], 0); //redirect stdin
execvp(args2[0], args2);
if(close(fd2[0])<0){ //close pipe after use
error();
}
exit(0);
}
//parent
//parent doesn't read from the pipe
if(close(fd1[0])<0){
error();
}
if(close(fd2[0])<0){
error();
}
if(close(fd2[1])<0){
error();
}
dup2(fd1[1], 1); //redirect stdout
for(i=1; i<=10000; i++){
write(1, &i, sizeof(i));
}
if(close(fd1[1])<0){
error();
}
int returnedPID1=waitpid(pid1, &status1, 0);
if(returnedPID1==pid1){
printf("Parent waited for child as predicted
");
}
int returnedPID2=waitpid(pid2, &status2, 0);
if(returnedPID2==pid2){
printf("Parent waited for child as predicted
");
}
_exit(0);
}

PZ

int main()
{
int n;
int i;
while((n=read(0, &i, 4))>0){
if((i%2)!=0){
write(1, &i, sizeof(i));
}
}
return;
}

多谢你们。


答案

除非出现错误,exec永远不会返回。所以当你写:

int main()
{
int n;
int i;
char tmp[12] = {0x0};
char *arg[]= {"/home/eric/Documents/pr3/test.txt"};
int fp = open(arg[0], O_WRONLY|O_CREAT|O_TRUNC, 0666);
if(fp<0){
printf("Error opening file
");
_exit(1);
}
while((n=read(0, &i, 4))>0){
if((i%3)!=0){
sprintf(tmp,"%11d", i);
write(fp, tmp, strlen(tmp));
}
}
return;
}

你希望关闭文​​件描述符是错误的。你执行前关闭它们。他们正在开放。虽然在你的特殊情况下问题是父节点永远不会关闭fd 1.父节点有两个文件描述符写入管道( execvp(args1[0],args1);
if(close(fd1[0])<0){ //close used pipe
error();
}
fd[1]),你需要在读取管道的子节点完成之前关闭它们。



推荐阅读
  • Zabbix自定义监控与邮件告警配置实践
    本文详细介绍了如何在Zabbix中添加自定义监控项目,配置邮件告警功能,并解决测试告警时遇到的邮件不发送问题。 ... [详细]
  • 函子(Functor)是函数式编程中的一个重要概念,它不仅是一个特殊的容器,还提供了一种优雅的方式来处理值和函数。本文将详细介绍函子的基本概念及其在函数式编程中的应用,包括如何通过函子控制副作用、处理异常以及进行异步操作。 ... [详细]
  • 所在位置|室友_Python+OpenCv实现图像边缘检测(滑动调节阈值)
    所在位置|室友_Python+OpenCv实现图像边缘检测(滑动调节阈值) ... [详细]
  • 大华股份2013届校园招聘软件算法类试题D卷
    一、填空题(共17题,每题3分,总共51分)1.设有inta5,*b,**c,执行语句c&b,b&a后,**c的值为________答:5 ... [详细]
  • Asynchronous JavaScript and XML (AJAX) 的流行很大程度上得益于 Google 在其产品如 Google Suggest 和 Google Maps 中的应用。本文将深入探讨 AJAX 在 .NET 环境下的工作原理及其实现方法。 ... [详细]
  • Python3爬虫入门:pyspider的基本使用[python爬虫入门]
    Python学习网有大量免费的Python入门教程,欢迎大家来学习。本文主要通过爬取去哪儿网的旅游攻略来给大家介绍pyspid ... [详细]
  • 本文详细介绍了在Luat OS中如何实现C与Lua的混合编程,包括在C环境中运行Lua脚本、封装可被Lua调用的C语言库,以及C与Lua之间的数据交互方法。 ... [详细]
  • Logging all MySQL queries into the Slow Log
    MySQLoptionallylogsslowqueriesintotheSlowQueryLog–orjustSlowLog,asfriendscallit.However,Thereareseveralreasonstologallqueries.Thislistisnotexhaustive:Belowyoucanfindthevariablestochange,astheyshouldbewritteninth ... [详细]
  • 【小白学习C++ 教程】二十三、如何安装和使用 C++ 标准库
    【小白学习C++ 教程】二十三、如何安装和使用 C++ 标准库 ... [详细]
  • 本文将深入探讨 Unreal Engine 4 (UE4) 中的距离场技术,包括其原理、实现细节以及在渲染中的应用。距离场技术在现代游戏引擎中用于提高光照和阴影的效果,尤其是在处理复杂几何形状时。文章将结合具体代码示例,帮助读者更好地理解和应用这一技术。 ... [详细]
  • Lua IO操作详解
    本文介绍了Lua中的IO操作,包括简单模式和完整模式下的文件处理方法,以及相关的系统调用。 ... [详细]
  • 使用 Jupyter Notebook 实现 Markdown 编写与代码运行
    Jupyter Notebook 是一个开源的基于网页的应用程序,允许用户在同一文档中编写 Markdown 文本和运行多种编程语言的代码,并实时查看运行结果。 ... [详细]
  • T15483.【清华集训2017模拟11.26】简单路径T25484.【清华集训2017模拟11.26】快乐树T35485.【清华集训2017模拟11.26】字符串T1结论题,结论很 ... [详细]
  • 非计算机专业的朋友如何拿下多个Offer
    大家好,我是归辰。秋招结束后,我已顺利入职,并应公子龙的邀请,分享一些秋招面试的心得体会,希望能帮助到学弟学妹们,让他们在未来的面试中更加顺利。 ... [详细]
  • 本文介绍了如何使用Python的Paramiko库批量更新多台服务器的登录密码。通过示例代码展示了具体实现方法,确保了操作的高效性和安全性。Paramiko库提供了强大的SSH2协议支持,使得远程服务器管理变得更加便捷。此外,文章还详细说明了代码的各个部分,帮助读者更好地理解和应用这一技术。 ... [详细]
author-avatar
你不懂_de_笑
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有