fifo Linux

From Noah.org
Revision as of 17:06, 15 November 2013 by Root (talk | contribs) (→‎Python Linux FIFO)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search


This demonstrates how easy it is to use Linux FIFO (named pipes).

First you need to create the FIFO inode. There are two commands you can use to do this. The two following commands are equivalent:

mknod --mode=666 event.fifo p
mkfifo --mode=666 event.fifo

Python Linux FIFO

#!/usr/bin/env python

# This demonstrates a Linux Named Pipe (FIFO) in Python.
# You can run the test as follows:
#     mkfifo event.fifo
#     ./fifo_test.py
#     echo "Hello 1" >> event.fifo 
#     echo "Hello 2" >> event.fifo 
#     echo "Hello 3" >> event.fifo 

while True:
    fifo_in = file ("event.fifo", "r")
    for line in fifo_in:
        print (line)

quirks

The two most unusual aspects of FIFOs are that they will block on opening until data is put into the FIFO, and that they will be non-blocking on read() calls, so typical file read loop logic will not work. The following example demonstrates the quirks and a primitive method to get around the non-blocking read behavior.

#!/usr/bin/env python

"""
This demonstrates a Linux Named Pipe (FIFO) in Python. FIFOs are
non-blocking. A read call will return with no data. Note that perversely the
open() call is blocking. It will block until something puts data into the
FIFO. Once data is available the open call will unblock and the program can
consume input. Once all input is consumed you may continue to read input, but
the calls to read will be non-blocking so you will get zero length strings
until more input is put into the FIFO. To get around this a primitive
generator is used, which adds blocking to a FIFO. It reads the FIFO in a
tight loop. A short sleep is added to the loop to reduce the load.

You can run the test as follows:
    ./fifo_test.py
    echo "Hello 1" >> event.fifo
    echo "Hello 2" >> event.fifo
    echo "Hello 3" >> event.fifo
"""

import sys
import os
import stat
import time


def readerator(fd):

    """This reads data in a tight loop from a non-blocking file-descriptor.
    When data is found it is yielded. A short sleep is added when no
    data is available."""

    while True:
        data = os.read(fd, 10)
        if not data:
            time.sleep(0.1)
        else:
            yield data

os.mknod('event.fifo', 0666 | stat.S_IFIFO)
print("The open() call will block until data is put into the FIFO.")
fifo_in = os.open('event.fifo', os.O_RDONLY)
print("The open() call has unblocked.")
while True:
    for cc in readerator(fifo_in):
        sys.stdout.write(cc)

Java Linux FIFO

/* This demonstrates a Linux Named Pipe (FIFO) in Java.
 *
 *     mkfifo event.fifo
 *     javac fifo_test.java 
 *     java test
 *     echo "Hello 1" >> event.fifo 
 *     echo "Hello 2" >> event.fifo 
 *     echo "Hello 3" >> event.fifo 
 */
import java.io.*;

public class fifo_test
{
    public static void main(String args[]) throws IOException
    {
        String input_event;
        while (true){
            BufferedReader br = new BufferedReader(new FileReader("event.fifo"));
            while (true){
                input_event = br.readLine();
                if (input_event == null) break;
                System.out.println (input_event);
            }
        }
    }
}