打开命名管道的顺序会导致可能的竞争条件吗?

tir*_*der 4 c ipc pipe named-pipes

我正在尝试通过命名管道使用 IPC 在两个进程之间创建非常基本的客户端服务器通信。

我有 2 个管道,即fifo_clientfifo_server

我有以下两个类fifoclient.c,并且fifoserver.c具有以下代码行来打开两个管道。

fifoclient.c

int client = open("fifo_client",O_WRONLY);
int server = open("fifo_server",O_RDONLY);
Run Code Online (Sandbox Code Playgroud)

fifoserver.c

int client = open("fifo_client",O_RDONLY);
int server = open("fifo_server",O_WRONLY);
Run Code Online (Sandbox Code Playgroud)

然而,只要简单地改变打开clientserver管道的顺序fifoserver.c,程序就会冻结。

冻结时代码是这样写的:

fifoserver.c

int server = open("fifo_server",O_WRONLY);
int client = open("fifo_client",O_RDONLY);
Run Code Online (Sandbox Code Playgroud)

请注意,在这种情况下server,管道先于管道打开client。这会导致程序不响应(可能是竞争条件?)。

有人可以解释发生了什么以及为什么吗?

编辑:

这是两个类的完整代码:

fifoserver.c

#define BUFSIZE 20
#include<stdio.h>
#include<fcntl.h>
int main()
{

    char buf[BUFSIZE];
    int client = open("fifo_client",O_RDONLY);
    int server = open("fifo_server",O_WRONLY);
    if( server<0 || client < 0)
    {
        printf("Couldn't open file\n");
        exit(1);
    }

    read(client,buf,BUFSIZE*sizeof(char));
    printf("Client Says: %s\n",buf);
    write(server,"Fine, Thank You!",BUFSIZE*sizeof(char));
    close(server);
    close(client);      
    return 0;
}    
Run Code Online (Sandbox Code Playgroud)

fifoclient.c

#define BUFSIZE 20
#include<stdio.h>
#include<fcntl.h>
int main()
{
    char buf[BUFSIZE];
    int client = open("fifo_client",O_WRONLY);
    int server = open("fifo_server",O_RDONLY);
    if(client <0 || server <0)
    {
         printf("ERROR! Couldn't open file!\n");
         exit(1);
    }
    write(client,"Hello! How are you?",BUFSIZE*sizeof(char));
    read(server,buf,BUFSIZE*sizeof(char));
    printf("Server Says: %s\n",buf);
    close(server);
    close(client);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Fat*_*ror 6

man 7 fifo

内核为至少一个进程打开的每个 FIFO 特殊文件维护一个管道对象。必须先打开 FIFO 两端(读和写),然后才能传递数据。通常,打开 FIFO 会阻塞,直到另一端也打开为止。

换句话说,您的open()调用将阻塞,直到管道的另一端有进程为止。这不是竞争条件,而是死锁。如果进程不以相同的顺序打开管道,它们将永远相互等待。因此,正如您所注意到的,解决方案是它们必须以相同的顺序打开 fifo。