Monday, July 06, 2009
Linux FIFO
FIFO stands for "First in/First out", a part of interprocess communication mechanism. FIFO actually a named pipe (see manual page about pipe) used for communication between unrelated process. The kernel share it to be a part of file system, so multiple process can use (read/write) it concurrently. When data exchange occurs in a FIFO, the kernel passes all data internally without writing to the file system. Many real-time application use this method because it's unbuffered behavior, drastically reduce read/write process.
To create a FIFO, use mkfifo utility shipped by Linux's coreutils, in C way, we will need use mkfifo system call to create and then use it for read/write as like as working with a regular file.
Example to create FIFO:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int ret = mkfifo("/tmp/myfifo", 0666);
if (ret == -1)
perror("mkfifo");
If the call success it should create a FIFO named "/tmp/myfifo", then sender or receiver process can open and exchange data via read and write. Normally reading or writing from a FIFO should blocking, but in Linux, opening a FIFO with read and write access always success both in blocking or unblocking mode.
Sender:
int fd;
unsigned char cmd = 0xff;
fd = open("/tmp/myfifo", O_RDWR | O_NONBLOCK, 0666);
if (fd == -1) {
perror("open");
...
}
ret = write(cmd, &cmd, sizeof(cmd));
if (ret == -1) {
/* When write fails because the receiver has not opening the FIFO for reading, the kernel will send SIGPIPE (broken pipe) signal. */
perror("write");
...
}
Receiver:
int fd;
unsigned char cmd;
fd = open("/tmp/myfifo", O_RDWR | O_NONBLOCK, 0666);
if (fd == -1) {
perror("open");
...
}
ret = read(fd, &cmd, sizeof(cmd));
if (ret == -1) {
perror("read");
...
}
Because this blocking behavior, application programmer should be very careful when write their codes to prevent deadlocks.
Reference:
Linux manual page: mkfifo, FIFO.