Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read file with timeout in Python

Within Linux, there is a file, /sys/kernel/debug/tracing/trace_pipe, which as the name says, is a pipe. So, let's say I want to read the first 50 bytes from it using Python - and I run the following code:

$sudo python -c 'f=open("/sys/kernel/debug/tracing/trace_pipe","r"); print f; print f.read(50); f.close()<br>
<open file '/sys/kernel/debug/tracing/trace_pipe', mode 'r' at 0xb7757e90>

We can see that opening the file goes fast ( if we have the superuser permissions ) - however, if the trace_pipe file is empty at that moment, it will simply block ( and even if there is content, the content will be dumped until there is no more, and then again the file will block ). Then I have to press Ctrl-C to interrupt the Python script with a KeyboardInterrupt...

How can I have Python 2.7 do a read with timeout?

That is, I want to instruct Python to "try read 50 bytes from this file; if you don't succeed after one second, give up and return"?

like image 807
sdaau Avatar asked Jan 29 '14 11:01

sdaau


People also ask

How to put timeout in Python?

Then it's as simple as this to timeout a test or any function you like: @timeout(5.0) # if execution takes longer than 5 seconds, raise a TimeoutError def test_base_regression(self): ... Be careful since this does not terminate the function after timeout is reached!

Does Python have a timeout?

Since Python 3.5, there's a handy and recommended run() API in subprocess module, which has built-in timeout support. When timeout, it raises a TimeoutExpired exception.

How does timeout work in Python?

You can use signals and a context manager to acheive this. The idea is to register a function that will raise an exeption when the alarm signal is received and schedule the alarm signal for the timeout. Even if this solution works well, you can't nest timeout which can be a problem.

What is timeout requests?

The HyperText Transfer Protocol (HTTP) 408 Request Timeout response status code means that the server would like to shut down this unused connection. It is sent on an idle connection by some servers, even without any previous request by the client.


2 Answers

Use

os.read(f.fileno(), 50)

instead. That does not wait until the specified amount of bytes has been read but returns when it has read anything (at most the specified amount of bytes).

This does not solve your issue in case you've got nothing to read from that pipe. In that case you should use select from the module select to test whether there is something to read.

EDIT:

Testing for empty input with select:

import select
r, w, e = select.select([ f ], [], [], 0)
if f in r:
  print os.read(f.fileno(), 50)
else:
  print "nothing available!"  # or just ignore that case
like image 157
Alfe Avatar answered Sep 20 '22 16:09

Alfe


f = os.open("/sys/kernel/debug/tracing/trace_pipe", os.O_RDONLY|os.O_NONBLOCK)

Should prevent blocking (works in Unix only).. No need for select here..

like image 21
GabiMe Avatar answered Sep 17 '22 16:09

GabiMe