The simple part of your question is signal processing. In terms of Python runtime, the signal that was received while the interpreter was making a system call is presented to your Python code as an OSError exception with errno attributed to the corresponding errno.EINTR
So this probably works something like you expected:
#!/usr/bin/env python import signal, os, errno, time def handler(signum, frame):
Note. I have moved the time import from the function definition as it seems to be a bad shape to hide the import in this way. It’s not at all clear to me why you sleep in your signal handler and, in fact, this seems like a pretty bad idea.
The key point I'm trying to do is that any (not ignored) signal interrupts your main Python code execution line. Your handler will be called with arguments indicating which signal number caused execution (allowing you to use one Python function to process many different signals) and a frame object (which can be used for debugging or some kind of toolkit).
Since the main thread through the code is interrupted, you need to wrap this code when handling some exceptions in order to regain control after such events have occurred. (By the way, if you write code in C, you will have the same care, you should be prepared for any of your library functions with basic system calls to return errors and handle -EINTR in system errno, returning back to retrying or branching to any alternative in your main line (for example, switching to another file or without any file / input, etc.).
As other respondents indicated in their answers to your question, using your approach to SIGALARM is likely to be fraught with portability and reliability issues. Worse, some of these problems can be race conditions that you will never encounter in your test environment, and can only occur in conditions that are extremely difficult to reproduce. Ugly details are usually found in re-entry cases --- what happens if signals are sent during the execution of your signal handler?
I used SIGALARM in some scenarios and this was not a problem for me on Linux. The code I worked on was appropriate for the task. It may be adequate to your needs.
It's hard to answer your basic question without knowing more about how this Gnuradio code behaves, what objects you create from it, and which objects are returned.
Looking at the documents you contacted, I see that they do not seem to offer any “timeout” argument or parameter that can be used to limit the lock behavior directly. In the table in the section "Controlling the flow schedules", I see that they specifically say that .run() can be executed indefinitely or until SIGINT is received. I also note that .start() can start threads in your application and seems to return control to your Python code line while it works. (It seems to depend on the nature of your flow graphs, which I don't understand enough).
It looks like you could create your flow graphs, .start() them, and then (after some processing time or sleeping in your main Python code line) call the .lock() method on the control object (tb?). This, I suppose, puts the Python view of the state ... of the Python object ... in rest mode so that you can query the state or, as they say, reconfigure the flow schedule. If you call .run() , it will call .wait() after calling .start() ; and .wait() will apparently be executed until all the blocks “indicate that they are done” or until you call the object method .stop() .
It looks like you want to use .start() and neither .run() nor .wait() ; then call .stop() after doing any other processing (including time.sleep() ).
Maybe something simple:
tb = send_seq_2.top_block() tb.start() time.sleep(endtime - time.time()) tb.stop() seq1_sent = True tb = send_seq_2.top_block() tb.start() seq2_sent = True
.. although I am suspicious of my time.sleep() . You might want to do something else when you request the state of the tb object (perhaps as a result of sleeping for shorter intervals, calling its .lock() method and accessing attributes that I know nothing about, and then calling it .unlock() before going to bed again.