Search code examples
pythonunixsystem-callsnonblockingsingle-threaded

Use the system call select with files


I'm trying to write a single threaded non blocking program with the system call select. However, it doesn't work well using file handlers.

Here is the code:

import sys
import select

while True:
    file_handler = open('filename.txt')
    inputs = [file_handler, sys.stdin]
    try:
        _input, _output, _error = select.select(inputs, [], [])
    except select.error, e:
        print e

    for i in _input:
        txt = i.readline()
        if len(txt) > 0:
            print 'txt:', txt

It reaches the print message when there is a new input from stdin, but not when a new line is written to the file. It works perfectly fine when using sockets instead of files.


Solution

  • Which operating system are you using? Windows or UNIX or MacOS X or what?

    Traditionally, the select() call on UNIX-likes systems will return files as "always readable" and "always writable" so trying to use select() for I/O multiplexing will not be useful.

    On Windows, select() on files isn't expected to work at all, as it's a feature of the WinSock library.

    There are various "file notify" functions and APIs that may be better for your particular case -- Python even has some libraries that abstracts the OS specific code. However, that won't natively interact with sockets very well, so I believe the best way to get a program that both "reacts to input sockets" and "reacts to file changes" without using polling, is to create one or more Python threads.