命名管道,读取失败,文件描述符错误

时间:2017-07-05 13:13:02

标签: c linux pipe

我开始使用Linux下的管道,我的代码有问题。 我想测试通过fifo发送一个整数,所以我编写了一个小程序来测试它。

首先,我打开只读描述符,然后打开文档中预先编写的只写一个描述符。 我将数字发送到管道并关闭写描述符。

但是,当我试图从管道读取时,它说我有一个错误的文件描述符,我不明白为什么它不起作用,因为描述符是好的并且有很好的选择( O_RDONLY | O_NONBLOCK)。

这是我的代码:

void main(void)
{
    int modePipeWrite, modePipeRead;

    if(mkfifo("test.fifo", 0777) == -1)
    {
        perror("mkfifo");
        exit(EXIT_FAILURE);
    }
    if(modePipeRead = open("test.fifo", O_RDONLY | O_NONBLOCK) == -1)
    {
        perror("openRead");
        exit(EXIT_FAILURE);
    }
    if(modePipeWrite = open("test.fifo", O_WRONLY | O_NONBLOCK) == -1)
    {
        perror("openWrite");
        exit(EXIT_FAILURE);
    }


    int n = 0;

    if(write(modePipeWrite, &n, sizeof(n)) == -1)
    {
        perror("write");
    }
    printf("Send value: %d\n", n);

    close(modePipeWrite);


    int mode;

    while(1)
    {
        if(read(modePipeRead, &mode, sizeof(mode)) == -1)
        {
            perror("read");
        }
        printf("Received value: %d\n", getpid(), mode);
        sleep(1);
    }
}

输出:

./a.out
Send value: 0

read: Bad file descriptor
Received value: -1877110288

read: Bad file descriptor
Received value: -1877110288

read: Bad file descriptor
Received value: -1877110288

我不明白这里有什么不妥。如果有人有一些建议,我很乐意听到。

1 个答案:

答案 0 :(得分:0)

您的代码有几个问题,如果您在启用所有警告的情况下编译它,您会发现这些问题。如果您使用gcc,以下选项是好的/强制的:      -Wall -Wextra -Werror -pedantic

一个问题是您没有将open()的返回值赋给文件描述符。您需要在赋值周围添加大括号,或将其移出if语句。

这是一个工作示例,使用线程来阅读:

#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>

#include <pthread.h>

static void *reader(void *arg)
{   
    int fd, val;

    if ((fd = open("test.fifo", O_RDONLY)) == -1) {
        perror("openRead");
        exit(EXIT_FAILURE);
    }

    if (read(fd, &val, sizeof val) == -1)
        perror("read");
    else
        printf("Received value: %d\n", val);

    close(fd);
    return NULL;
}

int main(void)
{   
    int modePipeWrite, modePipeRead;
    pthread_t readerid;


    if (mkfifo("test.fifo", 0777) == -1) {
        perror("mkfifo");
        exit(EXIT_FAILURE);
    }
    pthread_create(&readerid, NULL, reader, NULL);
    sleep(1);

    if ((modePipeWrite = open("test.fifo", O_WRONLY)) == -1) {
        perror("openWrite");
        exit(EXIT_FAILURE);
    }

    int n = 1234;

    if (write(modePipeWrite, &n, sizeof n) == -1)
        perror("write");
    else
        printf("Sent value: %d\n", n);

    sleep(1);
    close(modePipeWrite);

    return 0;
}