Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order of opening named pipes causing possible race condition?

I am trying to create a very basic client server communication between two processes using IPC via named pipes.

I have 2 pipes, namely fifo_client and fifo_server

I have the following two classes fifoclient.c and fifoserver.c that has the following lines of code to open the two pipes.

fifoclient.c

int client = open("fifo_client",O_WRONLY);
int server = open("fifo_server",O_RDONLY);

fifoserver.c

int client = open("fifo_client",O_RDONLY);
int server = open("fifo_server",O_WRONLY);

However, on simply changing the order of opening the client and server pipes in fifoserver.c, the program freezes.

This is how the code is written when it freezes:

fifoserver.c

int server = open("fifo_server",O_WRONLY);
int client = open("fifo_client",O_RDONLY);

Notice that the server pipe is opened before the client pipe in this case. This leads to the program not responding (possible race condition?).

Can someone explain what is happening and why?

EDIT:

Here's the entire code for both the classes:

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;
}    

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;
}
like image 303
tirtha2shredder Avatar asked Oct 31 '25 02:10

tirtha2shredder


1 Answers

From man 7 fifo:

The kernel maintains exactly one pipe object for each FIFO special file that is opened by at least one process. The FIFO must be opened on both ends (reading and writing) before data can be passed. Normally, opening the FIFO blocks until the other end is opened also.

In other words, your open() call will block until there is a process on the other end of the pipe. This is not a race condition -- rather, it is a deadlock. If the processes do not open the pipes in the same order, they will wait forever on one another. So, as you noticed, the solution is that they must both open the fifos in the same order.

like image 180
FatalError Avatar answered Nov 03 '25 08:11

FatalError