【问题标题】:Writing into pipe always fails写入管道总是失败
【发布时间】:2018-12-07 22:08:12
【问题描述】:

我试图通过尝试将文本文件中的数据读取到第一个管道并在另一个管道上读取它来在 2 个进程之间进行通信,但写入函数总是失败:

主要:

int main(int argc, char* argv[])
{
    int readerPip[2], writerPip[2], reader, writer;

    if (pipe(readerPip))
    {
      fprintf (stderr, "Pipe failed.\n");
      return EXIT_FAILURE;
    }

    if(pipe(writerPip))
    {
      fprintf (stderr, "Pipe failed.\n");
      return EXIT_FAILURE;
    }

    close(readerPip[1]); // closing reader writing side pipe for main thread
    reader = fork();
    if (reader < 0)
    {
        perror("Cannot fork()");
        exit(EXIT_FAILURE);
    }
    else if (reader == 0)
    {
        do_reader(readerPip);
    }

    wait(NULL);
    close(writerPip[0]); // closing writer reader side pipe for main thread
    do_father(readerPip, writerPip);
    close(readerPip[0]); // closing reader reader side pipe for main thread
    close(writerPip[1]); // closing writer writing side pipe for main thread
    writer = fork();

    if (writer < 0)
    {
        perror("Cannot fork()");
        exit(EXIT_FAILURE);
    }
    else if (writer == 0)
    {
        do_writer(writerPip);
    }

    return 1;
}// main

do_Reader:

void do_reader(int readerPipe[])
{
    char stringCommand[17];
    long long unsigned command;

    close(readerPipe[0]);
    while (1)
    {
        scanf("%s", stringCommand);
        command = convertStringToPolygon(stringCommand);

        if ((command & 0xFFFFFFFF) == 0xFFFFFFFF)
        {
            break;
        }

        if (write(readerPipe[1], stringCommand, strlen(stringCommand) ) == -1)
        {
            printf("writing falied");
        }
        else
        {
            printf("success");
        }

        printf("\n");
    }

    close(readerPipe[1]);
    exit(0);
}

do_father

void do_father(int readerPipe[], int writerPipe[])
{
    long long unsigned nbytes;
    char currentPolygon[17];
    currentPolygon[16] = '\0';
    while (1)
    {
        nbytes = read(readerPipe[0], currentPolygon, sizeof(currentPolygon));
        if (nbytes == 0)
        {
            printf("done");
            break;
        }

        manageProgram(readerPipe, writerPipe,        convertStringToCommand(currentPolygon));
    }
}

do_writer

void do_writer(int pip[])
{
    close(pip[1]);
    long long unsigned command, nbytes;

    while (1)
    {
    nbytes = read(pip[0], &command, sizeof(command));
        if (nbytes == 0)
        {
            break;
        }
        if ((((command & THIRD_BIT_MASK) != FALSE) || ((command & FORTH_BIT_MASK) 
!= FALSE) ||
            ((command & FIFTH_BIT_MASK) != FALSE)) != FALSE)
            generateOutputDependsOnBits(command);
    }

    close(pip[0]);
    exit(0);
}

其余代码无关紧要,因为为阅读器管道编写代码不起作用。 文本文件如下所示:

3a 0000050000050505 3e 003cc40000c43c3c 巴 000088ec9c32ce32 f8 抄送 3a 000085ec9a32cd32 4c 8c 5c 交流 fd FFFFFFFFFFFFFFFF

【问题讨论】:

  • 问一个关于运行时问题的问题,因为这个问题正在做,请发minimal reproducible example,以便我们重新创建问题,以便我们可以帮助您调试它。
  • OT:为了便于阅读和理解:1) 单独的代码块:for if` else while do...while switch case default 通过单个空格线。 2) 一致地缩进代码。在每个左大括号“{”后缩进。在每个右大括号 '}' 之前取消缩进。建议每个缩进级别为 4 个空格
  • 功能在哪里/是什么:do_write()do_father()
  • fork() 函数返回三个指示: >0 表示父进程 =0 表示子进程
  • 函数的返回值:fork() 定义为pid_t 目前,这是int 的别名,但不能依赖该别名

标签: c linux process pipe fork


【解决方案1】:

您在main 中关闭readpipe[1]之前 fork)并在do_reader 中关闭readpipe[0],所以管道的两边封闭在孩子身上。

main 中的close(readpipe[1]) 向下移动(例如,在wait 之前)。

但是,你可能不想在那里wait。您可能希望在do_father 之后执行此操作,因为这将依赖于内核管道缓冲区足够大以容纳 所有 子级在父级甚至尝试获取第一个字节之前发送给父级的数据.

【讨论】:

  • 同样的问题也出现在`writepipe[]
  • 所以在我关闭主进程的读取器管道之前等待功能应该是正确的?
猜你喜欢
  • 1970-01-01
  • 2011-07-13
  • 1970-01-01
  • 2020-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-18
相关资源
最近更新 更多