As an extension to a previous post that unfortunately seems to have died a death: select.select issue for sockets and pipes. Since this post I have been trying various things to no avail and I wanted to see if anyone has any idea where I am going wrong. I'm using the select() module to identify when data is present on either a pipe or a socket. The socket seems to be working fine but the pipe is proving problematic.
I have set up the pipe as follows:
pipe_name = 'testpipe'
if not os.path.exists(pipe_name):
os.mkfifo(pipe_name)
and the pipe read is:
pipein = open(pipe_name, 'r')
line = pipein.readline()[:-1]
pipein.close()
It works perfectly as a stand alone piece of code but when I try and link it to the select.select function it fails:
inputdata,outputdata,exceptions = select.select([tcpCliSock,xxxx],[],[])
I have tried entering 'pipe_name', 'testpipe' and 'pipein' in the inputdata argument but I always get a 'not defined' error. Looking at various other posts I thought it might be because the pipe does not have an object identifier so I tried:
pipein = os.open(pipe_name, 'r')
fo = pipein.fileno()
and put 'fo' in the select.select arguments but got a TypeError: an integer is required. I have also had a Error 9: Bad file descriptor when using this configuration of 'fo'. Any ideas what I have done wrong would be appreciated.
EDITED CODE: I have managed to find a way to resolve it although not sure it is particularly neat - I would be interested in any comments- Revised pipe setup:
pipe_name = 'testpipe'
pipein = os.open(pipe_name, os.O_RDONLY)
if not os.path.exists(pipe_name):
os.mkfifo(pipe_name)
Pipe Read:
def readPipe()
line = os.read(pipein, 1094)
if not line:
return
else:
print line
Main loop to monitor events:
inputdata, outputdata,exceptions = select.select([tcpCliSock,pipein],[],[])
if tcpCliSock in inputdata:
readTCP() #function and declarations not shown
if pipein in inputdata:
readPipe()
It all works well, my only problem now is getting the code to read from the socket before any event monitoring from select gets underway. As soon as connection is made to the TCP server a command is sent via the socket and I seem to have to wait until the pipe has been read for the first time before this command comes through.
According to the docs, select needs a file descriptor from os.open
or similar. So, you should use select.select([pipein], [], [])
as your command.
Alternatively, you can use epoll
if you are on a linux system.
poller = epoll.fromfd(pipein)
events = poller.poll()
for fileno, event in events:
if event is select.EPOLLIN:
print "We can read from", fileno
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With