【问题标题】:Broken pipes in C -- pipe(), fork(), exec() programC 中的管道损坏——pipe()、fork()、exec() 程序
【发布时间】:2009-01-25 23:54:01
【问题描述】:

我需要编写一个简单的程序:将有一个 Parent 和几个程序 [children](通过 Parent 中的 execl 开始)。孩子们以这种方式相互交流:孩子我感知到父母编号 J,父母向 J 发送消息(类似于 - “有一条消息给你”),J 发送给父母编号 K 等等。

还有一个问题——我的程序(通过strace 命令测试)尝试向孩子发送消息,然后出现了管道损坏错误。

如果有人查看代码并告诉我出了什么问题,我将不胜感激:

代码如下:

/**
 * Arbiter zabawy w Losia
 *

 wersja: Alfa 3b
 początek edycji 25.01.2009
 */

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "err.h"

pid_t pid;
FILE *a;

int main ()
{
    // my N players
    int N;
    N = 10;
    //write -- writing from parent to child 
    //read -- reading from child
    int rurka_write[N+1][2]; 
    int rurka_read[N+1][2];
    //initiation of N players
    int i;
    for(i = 1; i <= N; i++)
    {
        //tworze lacza
        if (pipe(rurka_write[i]) == -1)
            printf("wystapil blad przy rurce %d\n", i);
        if (pipe(rurka_read[i]) == -1)
            printf("wystapil blad przy rurce %d\n", i); 
    }
    for(i = 1; i <= N; i++)
    {
        switch(pid = fork())
        {
            case -1: 
                printf("wystapil blad przy forkowaniu");
            case 0:
                printf("potomek numer %d\n", i);
                if (close(rurka_write[i][1]) == -1)
                    printf("zle zamykanie");
                if (close(rurka_read[i][0]) == -1)
                    printf("zle zamykanie");

                //closing useless descriptors
                int j;
                for(j = 1; j <= N; j++)
                {
                    if (j != i)
                    {
                        close(rurka_read[j][0]);
                        close(rurka_read[j][1]);
                        close(rurka_write[j][0]);
                        close(rurka_write[j][1]);
                    }
                }   

                char str_N[20];
                char str_i[20];
                char str_0[20];
                char str_1[20];

                sprintf(str_N, "%d", N);
                sprintf(str_i, "%d", i);
                sprintf(str_0, "%d", rurka_write[i][0]);
                sprintf(str_1, "%d", rurka_read[i][1]);

                printf("%d Executing execl\n", i);
                execl("./ucz", str_N, str_i, str_0, str_1, NULL);
                printf("execl executed\n");
//              execv("./ucz", str_N, str_i, str_0, str_1, NULL);
                //exit(0);
            default:
                //closing useless pipes
                if (close(rurka_read[i][1]) == -1)
                    printf("zle zamykanie rurki do czytania z potomkna\n");
                if (close(rurka_write[i][0]) == -1)
                    printf("zle zamykanie rurki do pisania do potomka\n");
        } //end of switch

    } //end of for
    //if I am in parent, I'm starting the game
    if (pid != 0)
//  delay(100);
    {
        printf("PLAY\n");
        int l = 1;
        while(l > 0)
        {
            printf("sending to player %d\n", l);
            a = fdopen(rurka_write[l][1], "w");
            printf("sending: Wake up");
            fprintf(a, "Wake up\n");
            printf("flushing");
            fflush(a);
            char k[20];
            printf("reading");
            read(rurka_read[l][0], k, 20);
            l = k;
        }
    }
}

【问题讨论】:

  • 你应该把你的错误和你的代码一起发布。
  • 我认为你的程序有一个错误:我认为你的意思是用'break;'来完成你的case语句。
  • 如果没有看到“ucz”对其参数做了什么,我真的无法回答。此外,您应该在 exec* 之后退出/中止(因为除非发生错误,否则 exec 不应该返回,并且它通常会与您的代码流混淆)

标签: linux exec fork pipe


【解决方案1】:

除了您不以break 结束您的案件(正如strager 所指出的)之外,主要问题是声明l = k;。请注意,kchar[20],当分配给 int 时,您不会将 k 的任何内容分配给 l。相反,l 将包含指向数组的指针(值)。您将不得不在这里做一些不同的事情来获取数组中的值;究竟取决于ucz 发回的内容。

修复此问题并制作我自己的ucz 后,该程序似乎可以正常运行。当然也可能是你的ucz版本有问题。

【讨论】:

    【解决方案2】:

    关于 ./ucz -- 它需要 4 个参数 -- 1st -- 玩家数量,2nd -- 玩家数量,3rd -- 从父级读取的描述符数, 4th -- 要写入父级的描述符数。

    在 exec 之后(或在 "case: 0" 的末尾)添加 exit(0)、return(0)、break 没有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-06
      • 2020-05-07
      • 1970-01-01
      • 2014-06-09
      • 2014-05-31
      • 2011-03-20
      • 2011-07-02
      • 2013-05-28
      相关资源
      最近更新 更多