mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* how best to handle multiple readers on a fifo?
@ 2002-01-23 19:41 Mark Frazer
  0 siblings, 0 replies; only message in thread
From: Mark Frazer @ 2002-01-23 19:41 UTC (permalink / raw)
  To: Linux Kernel

Basically, I have a daemon process which I want to periodically check
a fifo node made with mknod (STAT_FILE, S_IFIFO | 0444, 0) and spit up
a status message.

Something like this:
        writefd = open (STAT_FILE, O_NDELAY | O_WRONLY);
        if (writefd > 0) {
                int len;
                len = give_ctrl_status (writefd);
                close (writefd);
        } else if (errno != ENXIO) {
                error ("Error (%s) reading " STAT_FILE, strerror (errno));
                all_done = 1;
        }


Yay.  All's well until there's multiple processes consuming the message
out of STAT_FILE.

The bash script below simulates the problem.  If there's multiple readers,
only one of them gets the message out of the fifo.  This is not a Linux
specific deal, Solaris does it too.

Here's the output of the script on Linux:
[mjfrazer@frogger fifo]$ ./fifo.test 
after 1000 iterations:
winner[1] = 999
winner[2] = 1
winner[3] = 0
winner[4] = 0
[mjfrazer@frogger fifo]$ uname -a
Linux frogger 2.4.17 #1 Fri Jan 18 16:06:33 EST 2002 i686 unknown

and on Solaris:
[mjfrazer@toronto-fs fifo]$ ./fifo.test 
after 100 iterations:
winner[1] = 19
winner[2] = 18
winner[3] = 16
winner[4] = 47
[mjfrazer@toronto-fs fifo]$ uname -a
SunOS toronto-fs 5.8 Generic_108528-10 sun4u sparc SUNW,Ultra-4

As far as I can tell, I'm borked.  What think the filesystem types
of adding a flag to mknod or something to tell the pipe not to boot off
unserviced readers?

-mark


#!/bin/bash

if [ `uname` = Linux ] ; then
        MAX=1000
        WAIT='usleep 100000'
elif [ `uname` = SunOS ] ; then
        MAX=100
        WAIT='sleep 1'
else
        echo "Only runs on Solaris or Linux"
        exit 1
fi

readers="1 2 3 4"

for i in $readers ; do
        winner[$i]=0
done

iter=0
while [ $iter -lt $MAX ] ; do
        echo -ne "  $(( $iter + 1 )) \r"

        /bin/rm -f fifo
        mkfifo fifo

        trap "echo hello > fifo" INT

        for i in $readers ; do
                cat fifo > out.$i &
        done
        $WAIT

        # ps -ef | grep 'cat fifo' | grep -v grep
        echo hello > fifo

        trap - INT

        wait
        ps -ef | grep 'cat fifo' | grep -v grep

        for i in $readers ; do
                if [ -s out.$i ] ; then
                        # echo winner is $i
                        winner[$i]=$(( ${winner[$i]} + 1 )) ;
                fi
        done
        iter=$(( $iter + 1 ))
done

echo "after $iter iterations:"
for i in $readers ; do
        echo winner\[$i] = ${winner[$i]}
done

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2002-01-23 19:41 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-01-23 19:41 how best to handle multiple readers on a fifo? Mark Frazer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®