Could Emacs be rewritten in Python?
Robin Munn
rmunn at pobox.com
Tue Apr 15 17:45:02 EDT 2003
Paul Foley <see at below.invalid> wrote:
> On Mon, 14 Apr 2003 16:50:40 GMT, Robin Munn wrote:
>
>> What I really want to know is why you would consider sample #1 "broken
>> and fragile code". I can't think of any circumstances where sample #1
>> would fail to achieve its desired effect. Can you?
>
> What if another thread (B) does the same thing, and changes sys.stdout
> while this thread (A) is still inside the "try" block? And if thread
> A runs its "finally" clause and resets sys.stdout while thread B is
> still in its "try" block, they screw each other.
This is the classic problem that arises when two threads need to use any
shared resource, isn't it? I wasn't considering threads at all when I
wrote those two code samples, so of course I didn't use locks to ensure
good behavior.
Actually, now that I start thinking about it, any kind of
save-and-restore mechanism would start to get pretty hairy around
threads, wouldn't it? Let's look at a hypothetical "with" construct:
with sys.stdout = cStringIO.StringIO():
function_that_prints()
parse_text_from(sys.stdout)
Let's assume we have two threads executing this code, and that the
"with" statement uses thread-local storage to save the original values.
If the "with" statement implements some kind of locking mechanism, this
is what you'll get:
----------------------------------------------------------------------
Thread A: Thread B:
(saves sys.stdout)
function_that_prints()
parse_text_from(sys.stdout)
(restores sys.stdout)
(saves sys.stdout)
function_that_prints()
parse_text_from(sys.stdout)
(restores sys.stdout)
----------------------------------------------------------------------
No problems here, of course. But what if this execution order happens?
----------------------------------------------------------------------
Thread A: Thread B:
(saves sys.stdout)
(saves sys.stdout)
function_that_prints()
function_that_prints()
parse_text_from(sys.stdout)
(restores sys.stdout)
parse_text_from(sys.stdout)
(restores sys.stdout)
----------------------------------------------------------------------
Thread B's parse_text_from() will be trying to read from thread A's
original sys.stdout, which will probably fail.
I don't really see any good solutions other than a lock around the whole
with: statement, which is something that would be easy to do in a try
... finally block. But maybe you can come up with something.
--
Robin Munn <rmunn at pobox.com>
http://www.rmunn.com/
PGP key ID: 0x6AFB6838 50FF 2478 CFFB 081A 8338 54F7 845D ACFD 6AFB 6838
More information about the Python-list
mailing list