Linux C 中子级和父级之间的管道示例

如何解决Linux C 中子级和父级之间的管道示例

这看起来很简单,中间的一个管道,父进程会在管道的写端写入管道,子进程会在while循环中从管道中读取,并打印读取的内容,但是我的程序无法停止...

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"

int
main(int argc,char *argv[]){
  int fd[2];
  int number;
  int write_number[1];
  pipe(fd);
  int pid;
  if ((pid = fork()) >0){
     close(fd[0]);
     for (int i = 2; i < 36; i++){
         *write_number = i;
         write(fd[1],write_number,4);
     }
     printf("write finished from parent process:%d\n",pid);
     close(fd[1]);
  }else{// child process
     close(fd[1]);
     while(read(fd[0],&number,4))
        printf("The number is %d from child %d\n",number,getpid());
     close(fd[0]);
  }
  exit(0);
}

顺便说一下,这是来自 xv6 类 Unix 系统,但我认为这与 Linux 中的几乎相同,输出:

$ primes
The numbwerite finished from parent prorc eis ss:24
 from $ child 4
The number is 3 from child 4
The number is 4 from child 4
The number is 5 from child 4
The number is 6 from child 4
The number is 7 from child 4
The number is 8 from child 4
The number is 9 from child 4
The number is 10 from child 4
The number is 11 from child 4
The number is 12 from child 4
The number is 13 from child 4
The number is 14 from child 4
The number is 15 from child 4
The number is 16 from child 4
The number is 17 from child 4
The number is 18 from child 4
The number is 19 from child 4
The number is 20 from child 4
The number is 21 from child 4
The number is 22 from child 4
The number is 23 from child 4
The number is 24 from child 4
The number is 25 from child 4
The number is 26 from child 4
The number is 27 from child 4
The number is 28 from child 4
The number is 29 from child 4
The number is 30 from child 4
The number is 31 from child 4
The number is 32 from child 4
The number is 33 from child 4
The number is 34 from child 4
The number is 35 from child 4

它没有停止,所以它挂起,但我已经关闭了我应该关闭的文件描述符,所以如果没有读取任何内容,读取系统调用应该返回 0,为什么它仍然挂起,所以任何人都可以帮我一把?谢谢!

解决方法

它确实停止了——在孩子打印“The number is 3 from the child 4”之前,父母退出并在混乱的输出中从shell中产生提示:

$ primes
The numbwerite finished from parent prorc eis ss:24
 from $ child 4
The number is 3 from child 4

您可能应该让父进程在带有 wait()waitpid() 函数的循环中等待,以便子进程在父进程退出和 shell 重新提示之前完成。

#include <sys/wait.h>

…

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

虽然不太可能,但进程有可能有当前程序没有分叉的子进程——而且循环也适用于这种情况。

切线注释:

  1. 由于您忽略命令行参数,因此最好使用 int main(void)

  2. exit(0); 不是必需的。您可以省略它,如果您在 C99 或更高版本的模式下编译,该进程将以零退出。这只是 main() 函数的特殊规则。就我个人而言,我更喜欢在 return 0; 末尾使用显式 main()

  3. 你有:

     for (int i = 2; i < 36; i++){
         *write_number = i;
         write(fd[1],write_number,4);
     }
    

您可以使用:

    for (int i = 2; i < 36; i++)
        write(fd[1],&i,sizeof(i));

使用 sizeof() 是惯用的;使用 4 容易出错。并且不需要 write_number 数组。

  1. 标题的选择是常规的。您应该使用 <stdio.h><unistd.h><sys/wait.h>。您实际上并不需要 <sys/types.h>。内核头文件应该只在编译代码以在内核中运行时使用——这个程序不是内核代码。

你说:

我加了一些像printf("child process is finished")这样的代码,在子条件下打印,但是exit(0)之前没有wait(0),表示子进程没问题,它会从管道关闭,但最后程序没有完成,只是挂在那里似乎在等待输入,我认为这是父退出但不等待孩子退出()的情况,但孩子确实在结束,但他的程序没有完成......最后的困惑

IMO,您的代码应如下所示:

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

int main(void)
{
    int fd[2];
    pipe(fd);
    int pid;
    if ((pid = fork()) > 0)
    {
        close(fd[0]);
        for (int i = 2; i < 36; i++)
            write(fd[1],sizeof(i));
        close(fd[1]);
        printf("write finished from parent process:%d\n",pid);
        int status;
        int corpse;
        while ((corpse = wait(&status)) > 0)
        {
            printf("%d: child %d exited with status 0x%.4X\n",(int)getpid(),status);
        }
    }
    else if (pid < 0)
    {
        fprintf(stderr,"failed to fork\n");
        return 1;
    }
    else
    {
        int number;
        close(fd[1]);
        while (read(fd[0],&number,sizeof(number)) > 0)
            printf("The number is %d from child %d\n",number,getpid());
        close(fd[0]);
    }
    return 0;
}

我得到的一个示例输出(在运行 macOS Big Sur 11.2.3 的 MacBook Pro 上运行)是:

write finished from parent process:53072
The number is 2 from child 53072
The number is 3 from child 53072
The number is 4 from child 53072
The number is 5 from child 53072
The number is 6 from child 53072
The number is 7 from child 53072
The number is 8 from child 53072
The number is 9 from child 53072
The number is 10 from child 53072
The number is 11 from child 53072
The number is 12 from child 53072
The number is 13 from child 53072
The number is 14 from child 53072
The number is 15 from child 53072
The number is 16 from child 53072
The number is 17 from child 53072
The number is 18 from child 53072
The number is 19 from child 53072
The number is 20 from child 53072
The number is 21 from child 53072
The number is 22 from child 53072
The number is 23 from child 53072
The number is 24 from child 53072
The number is 25 from child 53072
The number is 26 from child 53072
The number is 27 from child 53072
The number is 28 from child 53072
The number is 29 from child 53072
The number is 30 from child 53072
The number is 31 from child 53072
The number is 32 from child 53072
The number is 33 from child 53072
The number is 34 from child 53072
The number is 35 from child 53072
53069: child 53072 exited with status 0x0000

如果输出通过管道传输到另一个程序,“write finished from parent process:53072”行出现在“退出”打印之前的末尾。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res