c - 为什么打开 FIFO 时进程会被阻塞

标签 c linux

我为 FIFO 编写了一个测试。服务器通过 FIFO 将字符串“hello”写入客户端。但似乎两个进程都被阻塞了。我认为 FIFO 已打开以供服务器和客户端进行写入和读取。但这两个进程没有输出任何内容。

/* FIFO test */

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

#define FIFOPATH  "/home/hel/fifo" // define file path 

int client(void);
int server(void);

int main(void)
{
    pid_t pid;

    /* create FIFO */
    if (mkfifo(FIFOPATH, S_IRUSR | S_IWUSR) < 0) {
        if (errno == EEXIST) { // already exists, ok 
        }

        /* error */
        else {
            exit(-1);
        }
    }
    /* create process */
    pid = fork();
    if (pid < 0) { // error, process exits.
        exit(-1);
    } else if (pid == 0) { // child, server
          server();

          return 0; // exit
    }

    /* parent, client */
    client();

    return 0;
}       

/* server */
int server(void)
{
    int ret;
    int fd;

    /* open fifo for writing */
    if ((fd = open(FIFOPATH, 0200)) < 0) {
        printf("%s\n", strerror(errno));
        return -1; // error
    }

    ret = write(fd, "hello", 5);
    close(fd);

    return 0;
}

/* client */
int client(void)
{
    char recvBuf[100];
    int fd;
    int ret;

    /* open fifo for reading */
    if ((fd = open(FIFOPATH, 0400)) < 0) {
        printf("%s\n", strerror(errno));
        return -1; // error
    }

    ret = read(fd, recvBuf, 5);
    printf("ret: %d %d\n", ret, fd);
    printf("client receive %s\n", recvBuf);

    close(fd);
    return 0;
}

最佳答案

您的代码有两个问题。第一个是主要问题。

  1. 传递给 openflags 参数不正确。它们不应该是您提供的 unix 文件权限标志。服务器应使用 O_WRONLY,客户端应使用 O_RDONLY
  2. write(fd, "hello", 5);read(fd, recvBuf, 5); 不会写入和读取字符串的终止 NUL 字符。但随后它会被打印为字符串:printf("client receive %s\n", recvBuf);。这会调用未定义的行为(即使程序很有可能看起来“工作”)。将 5 更改为 6

关于c - 为什么打开 FIFO 时进程会被阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38176494/

相关文章:

从 gcc 的中间文件编译目标文件

linux - sudo vim crontab vs sudo crontab e - 何时使用

将 C 头文件转换为 delphi

linux - Virtualbox 卡住了整个 Ubuntu 16.04.3 LTS

c# - C# 和 C 中 volatile 的区别

c++ - 等价于 C++ 中的 C NULL 函数指针?

linux - 使用 FUSE 挂载循环设备

python - 关闭 Python 守护进程时运行代码

无法制作 nLoader

将 Ascii 码转换为二进制码