【问题标题】:Reading in two steps from the same pipe从同一管道分两步读取
【发布时间】:2016-07-06 12:43:13
【问题描述】:

所以,基本上我有一段代码,其中父进程将数字打印到管道:

    for(i=0;i<n;i++)
            {
                j=i+1;
                nwrite=write(pa[1],&j,sizeof(j));
                if (nwrite==-1)
                        {
                    printf("\nWrite error,pipe closed\n");
                    exit(-1);
                        }
                if (nwrite==0)
                        {
                    printf("\nWrote 0!\n");
                    break;
                        }
            }

和一个通过两个不同步骤从该管道读取的孩子: 它首先读取所有偶数并将它们写入管道pb

    for(i=0;i<n;i++)
            { 
                nread=read(pa[0],&num,sizeof(num));
                if (nread==0)
                {
                    printf("\nNothing to read!\n");
                    break;
                }
                if (nread==-1)
                {
                    printf("\nRead error!\n");
                    exit(-1);
                }
                if (num%2==0)
               {
                        printf("\nPrinting on pipe pb: %d\n",num);
                        nwrite=write(pb[1],&num,sizeof(num));
                        if (nwrite==0)
                        {
                            printf("\nNothing to write!\n");
                            break;
                        }
                        if (nwrite==-1)
                        {
                            printf("\nwrite error!\n");
                            exit(-1);
                        }
                }
            }

然后它进入pause() 并等待另一个进程发送signal(SIGUSR1,handler); 收到信号后,继续执行 从管道中读取所有奇数并将它们写入pb 管道:

          for(i=0;i<n;i++)
            { 
                nread=read(pa[0],&num,sizeof(num));
                if (nread==0)
                {
                    printf("\nNothing to read!\n");
                    break;
                }
                if (nread==-1)
                {
                    printf("\nRead error!\n");
                    exit(-1);
                }
                if (num%2==1)
                {
                        printf("\nPrinting on pipe pb: %d\n",num);
                        nwrite=write(pb[1],&num,sizeof(num));
                        if (nwrite==0)
                        {
                            printf("\nNothing to write!\n");
                            break;
                        }
                        if (nwrite==-1)
                        {
                            printf("\nwrite error!\n");
                            exit(-1);
                        }
                 }
            }

问题是,对管道 pa 的第一个 read 调用(我得到了偶数)读取了所有管道内容。此后,来自管道pa 的第二个read 调用返回0,因为已读取所有数字。我想在第一步中仅读取偶数,然后在第二步中读取奇数,我可以不要这样做让父母只写偶数。 任何提示?谢谢大家。

I am really sorry for my bad indenting, I'm trying my best to solve this issue with my coding style.

【问题讨论】:

  • 你不能。但是您可以从管道中读取数据并将其写入常规文件,这样您就可以进行查找。或者您可以读取数据并将其写入两个不同的管道。一个很好的练习可能是将奇数写入一个管道,您将在同一个线程中读取......当您拥有太多数据时,您最终会阻塞自己,这是一个很好的练习来理解这个问题并找出一个分辨率。
  • 这很令人沮丧。我正在为考试而学习,它被明确写成使用相同的管道,而不是文件等其他东西。我认为这可能是一个分配错误。顺便感谢您的快速答复。
  • 也许练习的目的是让您将奇数存储在内存中,并动态增长该内存。
  • 这个练习应该是关于管道的......好吧,没关系,我会试着和我的教授一起弄清楚我应该如何处理这个作业。再次感谢您。

标签: c linux process pipe fork


【解决方案1】:

不要在管道上寻找。故事结束。

请不要使用 printf() 将错误消息传递到标准输出。如果使用 stdio.h,请使用 fprintf 并将它们定向到 stderr。否则,暂时将标准输出切换为标准错误,printf(),然后恢复:

    int save_stdout;
save_stdout = dup(1);
关闭(1);
重复(2);

    printf(...);

    关闭(1);
重复( 保存标准输出);

【讨论】:

  • 复制底层文件描述符是一个糟糕的主意!如果没有适当的刷新,您最终会将消息发送到错误的位置。
  • 您使用dup() 而不是dup2() 来指定新创建的fd 的数量假定该进程是单线程的(否则我认为另一个线程中的open 可能需要fd 1,除了在您执行此操作时另一个线程可能会打印到 stdout 的事实),并且 stdin 没有关闭。 (./a.out &lt;&amp;- 在标准输入关闭的情况下运行程序)。
  • dup2 也会为你关闭旧的 fd1。所以总而言之,dup2(2,1) 会好得多,但仍然是你不应该使用的丑陋黑客。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 2021-12-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多