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

关于系统调用的问题,如fork()和C中的pipe()。-QuestionsaboutSystmcallslikefork()andpipe()inC

#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<sy
   #include
   #include
   #include
   #include
   #include

   int main(int argc, char **argv){
       int n = atoi(argv[1]);
       int superdaddy = getpid();
       int p[n+1][2];
       int i=0;
       int cpid,output;
       int result = 0;

       if(pipe(p[0])<0){
           perror("1");
           return 1;
       }
       if(pipe(p[n])<0){
           perror("2");
           return 1;
       }
       output = p[0][1];
       if(getpid()==superdaddy){
           if(write(p[0][1],&result,sizeof(result))<0){
               perror("3");
               return 1;
           }
           if(close(p[0][1])<0){
               perror("4");
               return 1;
           }
       }
       while(1){
           if(i==n){
               if(read(p[n-1][0],&result,sizeof(result)<0)){
                   perror("5");
                   return 1;
               }
               result++;
               output = p[n][1];
               if(write(output,&result,sizeof(result))<0){
                   perror("6");
                   return 1;
               }
               if(close(p[n-1][0])<0){
                   perror("7");
                   return 1;
               }
               if(close(p[n][1])<0){
                   perror("8");      
                   return 1;
               }
               break;
           }
           i++;
           cpid = fork();
           if(cpid==0){
               if(i==n)
                   continue;
               if(pipe(p[i])<0){
                   perror("9");
                   return 1;
               }
               if(read(p[i-1][0],&result,sizeof(result))<0){
                   perror("10");
                   return 1;
               }
               result++;
               output = p[i][1];
               if(write(output,&result,sizeof(result))<0){
                   perror("11");
                   return 1;
               }
               if(close(p[i-1][0])<0){
                   perror("12");
                   return 1;
               }

               if(close(p[i][1]<0)){
                   perror("13");
                   return 1;
               }
               continue;
           }
           else if(cpid<0){
               perror("14");
               return 1;
           }
           break;
       }

       if(getpid()==superdaddy){
           wait(NULL);
           if(read(p[n][0],&result,sizeof(result))<0){
               perror("15");
               return 1;
           }
           printf("Result: %d\n",result);
           if(close(p[n][0])<0){
               perror("16");
               return 1;
           }
       }
       return 0;
   }

The Program aims to read a number n from command line and then forks n child process and create n pipes. process p0 will be parent of process p1, p1 will be parent of p2, so and so on. One variable (named result here) will be passed through pipes, every time it is passed it will be added by 1. So the output should be n as well. Pipe Fi connects Pi and P(i+1). Attached is my code.

该程序旨在从命令行读取数字n,然后派生n个子进程并创建n个管道。进程p0是进程p1的父进程,p1是进程p2的父进程,以此类推。一个变量(此处命名为result)将在管道中传递,每次传递时它将被1添加。所以输出也应该是n。管道Fi连接Pi和P(i+1)。附件是我的代码。

When n=1 or n=2, the program can output correctly, which is 1 and 2 correspondingly. However, when n=3, it gives me a bad file error at error 5. I have hand-tracked the code for the whole afternoon but got no idea what is wrong with it. Anyone could help? Appreciate it first!

当n=1或n=2时,程序可以正确输出,即1和2。然而,当n=3时,它在错误5处给出了一个错误的文件错误。整个下午我都在跟踪代码,但不知道它有什么问题。任何人都可以帮忙吗?先欣赏它!

1 个解决方案

#1


1  

when n=3, it gives me a bad file error at error 5.

当n=3时,它在错误5处给出了一个错误的文件错误。

This could be fixed by removing that if(close(p[i][1]<0)){ in your code, because you need to read from p[i][0] in your last iteration, i.e.

可以通过在代码中删除if(close(p[i][1]<0)){来解决这个问题,因为您需要在上一次迭代中从p[i][0]中读取数据,即。

if (i == n) {
    if(read(p[n-1][0],&result,sizeof(result)<0)){
        ...
    }
}

This is an implementation of your idea, I hope it may be helpful:

这是你的想法的实现,希望能有所帮助:

#include 
#include 
#include 
#include 
#include 

int
main(int argc, char *argv[])
{
    if (argc != 2) {
        fprintf(stderr, "Usage: %s N\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    int n = atoi(argv[1]);
    int pipes[n][2];
    int i, val;
    pid_t pid;

    val = 0;

    for (i = 0; i 

Testing run:

测试运行:

$ ./a.out 3
P 2005 writes 0
C 2006 read 0
P 2006 writes 1
C 2007 read 1
P 2007 writes 2
C 2008 read 2
2008 is going to leave.
2007 is going to leave.
2006 is going to leave.
2005 is going to leave.

Explanation:

解释:

The frame of that code is for (i = 0; i , which means it will create n pipes, and n new processes. In each iteration, the parent will write to pipes[i][1] and child will read from pipes[i][0]. Eventually, it will create a process chain connected by a series of pipes, and a value is passed down from the first process to the last through that series of pipes.

该代码的框架是(i = 0;我


推荐阅读
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 怀疑是每次都在新建文件,具体代码如下 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
author-avatar
莫小刚002
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有