Raw_input with readline in a daemon thread makes terminal textdisappear

J

John O'Hagan

I'm getting input for a program while it's running by using raw_input in a
loop in separate thread. This works except for the inconvenience of not having
a command history or the use of backspace etc.

That can be solved by loading the readline module; however, it results in a
loss of visible access to the terminal when the program ends: nothing is
echoed to the screen and the history is invisible (although it is there -
hitting return executes whatever should be there normally). The only way to
get it back is to close the terminal and open a new one.

Here is minimal code that reproduces the problem (python 2.5 on Linux):

from threading import Thread
import readline

get_input = Thread(target=raw_input)
get_input.setDaemon(True)
get_input.start()

If the thread is not set to daemon mode, there is no such problem (don't know
why this makes a difference), but in the real program, it needs to be a daemon
or it hangs the exit waiting for more input.

Any suggestions appreciated.

Thanks,

John
 
A

Aahz

I'm getting input for a program while it's running by using raw_input in a
loop in separate thread. This works except for the inconvenience of not having
a command history or the use of backspace etc.

That can be solved by loading the readline module; however, it results in a
loss of visible access to the terminal when the program ends: nothing is
echoed to the screen and the history is invisible (although it is there -
hitting return executes whatever should be there normally). The only way to
get it back is to close the terminal and open a new one.

Can you restructure your program so that input gets handled in the main
thread?
 
J

John O'Hagan

Can you restructure your program so that input gets handled in the main
thread?
I can, but then I can't Ctrl+C out of the main program (which is a thread in
that scenario). This applies with or without readline loaded. I have seen
some, um, threads on this subject, and from memory it's complicated.

The raw_input and readline docs mention that the former uses the latter for
history and line-editing features. I haven't been able to find out exactly how,
but a theory occurs to me that the pair together somehow temporarily "steal"
control of the command-line while raw_input is accepting input - at least this
would explain the missing command-line when raw_input is terminated in a
daemon thread.

Since posting this question, I worked around it by making the input loop
thread non-daemon, and having it run only while an Event object's flag is set -
it's unset at the end of the program. That way, I just have to hit return one
more time to let the loop find the unset flag and we can exit cleanly.

This has the unplanned benefit that the closing of the separate output window
(a terminal in a subprocess, listening on a socket) can also wait on the same
flag, so the workaround looks as if it's on purpose. ;)

Still open to any cleaner suggestions, of course.

Regards and thanks,

John
 
A

Aahz

I can, but then I can't Ctrl+C out of the main program (which is a thread in
that scenario). This applies with or without readline loaded. I have seen
some, um, threads on this subject, and from memory it's complicated.

I don't have time to test this myself, but this doesn't sound right; my
experience is that it's the main thread that needs to be handling input
in order to correctly catch signals (such as ctrl-C).
The raw_input and readline docs mention that the former uses the latter
for history and line-editing features. I haven't been able to find out
exactly how, but a theory occurs to me that the pair together somehow
temporarily "steal" control of the command-line while raw_input is
accepting input - at least this would explain the missing command-line
when raw_input is terminated in a daemon thread.

Certainly; readline is using the tty interface.
Since posting this question, I worked around it by making the input
loop thread non-daemon, and having it run only while an Event object's
flag is set - it's unset at the end of the program. That way, I just
have to hit return one more time to let the loop find the unset flag
and we can exit cleanly.

Unless you can get your input running in the main thread, this is
probably the best you can do.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,754
Messages
2,569,527
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top