Python and FIFO

I tried to understand FIFO using Python under linux, and I found strange behavior that I do not understand.

Below is fifoserver.py

 import sys import time def readline(f): s = f.readline() while s == "": time.sleep(0.0001) s = f.readline() return s while True: f = open(sys.argv[1], "r") x = float(readline(f)) g = open(sys.argv[2], "w") g.write(str(x**2) + "\n") g.close() f.close() sys.stdout.write("Processed " + repr(x) + "\n") 

and this is fifoclient.py

 import sys import time def readline(f): s = f.readline() while s == "": time.sleep(0.0001) s = f.readline() return s def req(x): f = open("input", "w") f.write(str(x) + "\n") f.flush() g = open("output", "r") result = float(readline(g)) g.close() f.close() return result for i in range(100000): sys.stdout.write("%i, %s\n" % (i, i*i == req(i))) 

I also created two FIFOs using mkfifo input and mkfifo output .

I don’t understand why, when I start the server (with python fifoserver.py input output ) and the client (with python fifoclient.py ) from two consoles after some requests, the client crashes with a “broken pipe” error to f.flush() . Please note that before the crash, I saw from several hundred to several thousand correctly processed requests that work fine.

What is the problem in my code?

+6
python linux broken-pipe fifo mkfifo
source share
2 answers

As mentioned in other comments, you have a race condition.

I suspect that in the event of a failure, the server is suspended after one of the following lines:

 g.write(str(x**2) + "\n") g.close() 

Then the client can read the result, print it on the screen and go back. Then it reopens f -, which succeeds because it is still open on the server side and is recording the message. Meanwhile, the server managed to close f . Then the flash on the client side makes a string call to write() on the pipe, which launches SIGPIPE , because now it is closed on the other side.

If I'm right, you should fix this by moving the f.close() server to << 26>.

+5
source share

I am not a unix expert, but I assume that you will end up working with a file closed in both processes, and then the record for writing will open. Since there is nothing to receive data, the pipe breaks.

I don’t understand why you open and close the pipe all the time.

Try to start a process that first reads the channel, let it open the channel, and it will sit waiting for data.

Then start the pipeline and ask him to pump out all the data that you want to send. He will stop if he moves forward. When the author closes the pipe, the reader receives zero bytes instead of locking and must close. IIRC, Python detects this and returns EOF.

0
source share

All Articles