A long time ago I opened IDLEfork bug 81789, which fixes two IDLE freezes, when doing things simultaniously - one is when executing something while a thread prints output, and the other is when interrupting the subprocess in the middle of running IDLE code.
Here is the message sent to idle-dev on March '04. Bugs item #817898, was opened at 2003-10-05 00:42 Message generated for change (Comment added) made by noamr You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=109579&aid=817898&group_id=9579 Category: None Group: None Status: Open Resolution: None Priority: 5 Submitted By: Noam Raphael (noamr) Assigned to: Nobody/Anonymous (nobody) Summary: Threads and output Initial Comment: Hello, If a thread writes output (into sys.stdin) while a command should be executed, the command you tried to execute never finishes executing, so you are stuck. For example, type this: >>> from threading import Thread >>> def f(): for i in range(200): print i, >>> t = Thread(target=f) >>> t.start() Now, while the numbers are showing, type Enter. After the numbers stopped showing, you'll notive that you can't execute anything, until you restart the shell. I noticed this because I wrote a function which executes at a seperate thread and writes to sys.stderr. If I try to execute something while the output is being printed, I get stuck. Bye, Noam ---------------------------------------------------------------------- >Comment By: Noam Raphael (noamr) Date: 2004-03-07 18:31 Message: Logged In: YES user_id=679426 First, another problem: If you press Ctrl+C while an exception is being printed, IDLE gets stuck. You can test it easily using this: >>> def f(n): 1/n f(n-1) >>> f(10) And here's the solution. The first problem (what I thought was threading) happens because when the subprocess prints output, the write() method of the Text is called, which calls its update() method, which causes Tkinter to handle pending events, including a request for execution. If this happens from a poll_subprocess call, the current pollresponse() call may receive the response for execution, and ignore it because it was called before the execution started. The second problem happens because the interrupt happens in the exception handling part of Executive's runcode(), and the main process doesn't know how to handle an exception which runcode() didn't handle. The solution for the first problem is to use the RPC's 'responses' dict. RPC puts a response in the dict if it finds a Condition matching the sequence number in its 'cvars' dict, so the solution puts a dummy Condition in cvars. This changes PyShell and RemoteDebugger, because they use PyShell.active_seq. Another change, to rpc.py, is that I added an optional argument for pollresponse(), which makes it quit after a certain period of time even if not all messages were handled - there's no need to wait for all messages to be handled in poll_subprocess. The solution for the second problem is to add a global variable to run.py, which states whether the subprocess should consider interrupt requests. It should consider them only when a user code is being executed. (The patch is against the current IDLE cvs, patched with my syntax improvements, but it works against unpatched IDLE too. I didn't check it against IDLEfork) Noam Raphael _______________________________________________ IDLE-dev mailing list [email protected] http://mail.python.org/mailman/listinfo/idle-dev
