子进程死亡后,父进程不会从FIFO中读取

如何解决子进程死亡后,父进程不会从FIFO中读取

所以。我必须从命名管道读取和写入,并且我尝试通过执行以下操作来完成此操作:父进程将命令写入FIFO,然后等待孩子死亡。子进程读取命令,然后在另一个FIFO中写入内容。父Parent从另一个FIFO读取消息并打印结果。我被限制使用fopen,因为在我的代码中,我在其他地方使用unisted的open,因此我没有nonblock标志。我将在下面附上摘要。另外,如果我在子进程上使用“ w”标志,则代码将完全冻结。我知道FIFO是一种阻止通讯的方式,但我不明白为什么我的父母无法阅读。预先感谢。

int main()
{
    FILE *fp1;
    FILE* fp2;
    unlink(FIFO_NAME1);
    unlink(FIFO_NAME2);
    //FIFO_NAME[1|2] is a macro containing the FIFO path
    if(mkfifo(FIFO_NAME1,0666) == -1)
    {
        printf("Something went wrong");
        return -1;
    }
    if(mkfifo(FIFO_NAME2,0666) == -1)
    {
        printf("Something went wrong");
        return -1;
    }
    while(1)
    {
        char command[MAX_SIZE];
        pid_t pid;
        if((pid=fork()) !=0)
        {
            //parent
                fgets(command,MAX_SIZE,stdin);

                if((fp1= fopen(FIFO_NAME1,"w")) == NULL)
                {
                    printf("Error");
                }
                fprintf(fp1,"%s",command);

                fclose(fp1);
                wait(SIGKILL);
                //it never prints this or execute past the wait
                printf("Here \n");

                char response[MAX_SIZE];
                if((fp2= fopen(FIFO_NAME2,"r"))==NULL)
                    perror("");

                fgets(response,fp2);
                fclose(fp2);
                //printf("%s",response);
            }

        
        else
        {
            //child
            char msg[MAX_SIZE];
                   if((fp1 = fopen(FIFO_NAME1,"r")) == NULL)

                {
                    printf("Error");
                }
                fgets(msg,fp1);
                fclose(fp1);

            
                if((fp2= fopen(FIFO_NAME2,"w+")) == NULL)
                {
                    printf("Error");
                }

                char buffer[MAX_SIZE];
                strcpy(buffer,"TEST MESSAGE");
       
                fprintf(fp2,buffer);
                fclose(fp2);

           
            fflush(stdout);
            kill(getpid(),SIGKILL);
        }

    }

}

解决方法

这里的基本问题是您不能半开FIFO。至少,除非您以非阻塞模式打开它以进行读取,否则不会这样做,而fopen()是无法做到的。通常,打开FIFO进行读取将一直阻塞,直到也打开了相同的FIFO进行写入为止,反之亦然。

在这方面,您对FIFO_NAME1感到满意。父母打开它进行写作,孩子打开它进行阅读。两者都完成后,它们都会继续。

但是随后父级调用wait()(参数也有错误,但这是一个单独的问题)。直到其子级之一终止,父级才能从该wait成功返回。只有这样,它才会尝试打开FIFO_NAME2(以供读取),但是由于子级已经终止,因此该FIFO不会被任何进程打开以进行写入,并且打开该FIFO的尝试将无限期地阻塞。

然后有一个孩子。仅由于您指定了模式"w+",它才能成功打开第二个FIFO,这样子级就可以同时满足对读取器的要求和对写入器的要求。但是,这很危险,因为如果子进程实际上并未消耗FIFO中的任何数据,那么它可能会通过尝试向其写入比内核一次愿意缓冲的数据更多的数据而死锁。而且,它不能达到您的通信目的,因为不能保证FIFO在停止为读取或写入而打开时将保留由孩子写入的数据。确实,可能没有。

您需要移动或删除wait()调用,如果选择前者,则需要检查文档以发现应该传递的参数类型。如果您愿意相信孩子不会填满管道的缓冲区,则可以将等待时间移至父对象打开FIFO_NAME2之后且尝试读取任何内容之前。就其本身而言,子进程应确保以只写模式打开第二个FIFO,以确保父子进程都在子进程开始写入之前先打开该FIFO。

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

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 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 -> 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("/hires") 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<String
使用vite构建项目报错 C:\Users\ychen\work>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)> insert overwrite table dwd_trade_cart_add_inc > select data.id, > data.user_id, > data.course_id, > date_format(
错误1 hive (edu)> insert into huanhuan values(1,'haoge'); 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> 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 # 添加如下 <configuration> <property> <name>yarn.nodemanager.res