管道实现卡在dup2命令中 [英] Pipe implementation stuck at dup2 command

查看:143
本文介绍了管道实现卡在dup2命令中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想制作一个简单的外壳,但是我坚持实现管道.这是我的代码中与管道有关的部分.如果您认为有帮助,我可以提供更多功能,但其余功能完全可以按预期运行.

I'm tying to make a simple shell, but I'm stuck implementing pipes. Here's the part of my code that pertains to the pipe. There's more I can put if you think it'll help, but the rest of it works exactly as expected.

    args[i] = NULL;
    p_flag = 1;
    int stop = i;
    // we have to fork again so we can write to a buffer file.
    // First we creat the pipe.
    if (pipe(p_file) == -1) {
      //check if the pipe failed
      fprintf(stderr, "There was an error creating the pipe\n");
    }
    switch (pid = fork()) {
    case 0:
      //Open up the input end of the pipe for writing.
      printf("test1\n");
      close(p_file[0]);
      printf("test2\n");
      dup2(p_file[1], 1);
      printf("test3\n");
      execvp(args[0], args);
      fprintf(stderr, "ERROR %s no such program.\n", line);
      exit(1);
      break;
    case -1:
      fprintf(stderr, "ERROR can't create child process!\n");
      break;
    default:
      wait();
      break;
    }
    /*
      at this point only the first child should still be running
      and since we waited we know that the buffer file has our input.
      Now we have to redirect our input to read from the buffer and
      run the rest of the commands normally. first the args array has
      to be cleaned up we want the commands past the pipe symbol to be
      in front.
    */
    int j = 0;
    stop++;
    while (args[stop] != NULL) {
      args[j] = args[stop];
      j++;
      stop++;
    }
    args[j] = NULL;
    close(p_file[1]);
    dup2(p_file[0], 0);

如您所见,我输入了一些打印语句来尝试弄清楚它到底卡在了什么地方,并且在程序永久停止旋转之前,我得到了test1test2的输出.我必须按ctrl + c才能得到提示.我不知道为什么它在执行dup2命令时会卡住.此代码段中唯一遗漏的重要内容是p_file的初始化,它是大小为2的数组(即int p_file[2];).

As you can see, I've put in some print statements to try and figure out where exactly it was getting stuck, and I get test1 and test2 output before the program sits processing forever spinning its wheels. I have to ctrl+c to get the prompt back. I don't know why it's stuck doing the dup2 command. The only important thing left out of this code snippet is initialization of p_file and it's an array of size two (i.e. int p_file[2];).

推荐答案

您有严重的误解.管道是一种进程间通信机制.通过管道进行通信的进程通常同时运行,而不是顺序运行.它们必须在通用实现中(例如由shell提供的实现)同时运行,因为每个管道只有一个有限的缓冲区,并且在缓冲区填满时对其写入将阻塞或失败.除非可以确定写入器在退出前不会填充管道的缓冲区,否则读取器必须准备就绪并等待消耗管道读取端的数据,然后才能期望写入器完成.

You have a serious misconception. Pipes are an inter-process communication mechanism. The processes communicating via a pipe generally run concurrently, not sequentially. They must run concurrently in a general-purpose implementation, such as one provided by a shell, because each pipe has only a finite buffer, and writes to it will block or fail when the buffer fills. Unless you can be certain that the writer(s) will not fill the pipe's buffer before exiting, the reader(s) must be ready and waiting to consume data from the read end of the pipe before the you can expect the writer(s) to finish.

因此,对于第一个进程,在启动第二个进程之前,对于wait()是错误的,这可能就是程序挂起的原因.相反,外壳程序必须为管道的每一端启动一个子进程,然后等待两者.

It is therefore wrong to wait() for the first process before starting the second, and this could be why your program hangs. Instead, the shell must start a child process for each end of the pipe, and then wait for both.

此外,正如我在评论中所写,您调用wait()时没有适当的参数.这会产生不确定的行为,它本身可能是无限期的等待,但也可能几乎是其他任何事情.

Additionally, as I wrote in comments, you call wait() without the proper arguments. This produces undefined behavior, which could itself be an indefinite wait, but which might also be almost anything else.

对于调试输出,@ Ctx在他自己的注释中解释了为什么您看不到期望的所有内容.但是,我看不出有任何理由怀疑您是否认为该程序在您中断之前一直处于挂起状态.

As for your debugging output, @Ctx explained in his own comment why you do not see everything you expected. I do not, however, see any reason to doubt your claim that the program hangs until you interrupt it.

这篇关于管道实现卡在dup2命令中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆