我开始使用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
我不明白这里有什么不妥。如果有人有一些建议,我很乐意听到。
答案 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;
}