Skip to main content

how well do you know python, part 5

I was reminded of this one while working on the Spyce/Durus demo to make it a better example of using Durus in a real application.

What is wrong with the following code?

A.py:

import time, threading

finished = False

def foo():
    import sys
    sys.stderr.write('testing')
    global finished
    finished = True

threading.Thread(target=foo).start()
while not finished:
    time.sleep(1)

B.py:

import A

print 'finished'

Update: fixed A.py so there was only one problem.

Comments

Anonymous said…
The most obvious thing wrong is that finished isn't declared global in A.foo() so I think the thread should run and complete but the global finished variable will never be True.

If that's it, you've done a good job of hiding a really obvious problem by introducing threading into the mix. It took me a while to see it because I was expecting something to be wrong with the threading logic.

Which is interesting. I've always sworn threading introduces a whole slew of new problems and should be avoided if at all possible but I never considered that it might also have the effect of hiding well-known problems. :)

Nice.
Jonathan Ellis said…
Actually, that wasn't the problem I intended -- oops! Fixed in the post now. (That's a hint for you -- the problematic behavior that remains gives the same symptom as leaving off the global. :)
Anonymous said…
I/O blocking... one writes to STDERR, the other to STDOUT (via print)? The correct way to do it would be to use a threading.Event object
Anonymous said…
Let me simplify what others are saying: "It uses threads."
Anonymous said…
Hmmm. Well I'm wrong. At least what I thought would work doesn't.

Did I mention how much I dislike threading? ;)
Anonymous said…
I presume the issue is that import sys blocks because of the GIL.

What actually *is* so bad about threading? And what do you use as a cross platform alternative?
Jonathan Ellis said…
Yes, the import blocks. It's actually a separate import lock though, not the GIL. (Unless you redefined GIL to stand for Global Import Lock, but that's not what most people mean. :)
Ian Bicking said…
I'm going to guess that lock has something to do with the threadsafety of imports (which are threadsafe), which means other threads can't access the module until it has finished loading... including perhaps the thread started from the module itself...?
Jonathan Ellis said…
Think of it as an RLock under the import hood: if thread One is doing an import, all other import statements will block until One is done before continuing.

So here, the deadlock is that the main thread has the import lock ("import A"), but since it's waiting for _t to set finished, it will never release the lock and _t is forever stuck at "import sys."
Anonymous said…
The real lesson here is: don't start threads as a side effect of import.
Tim Lesher said…
Nice.
Anonymous said…
I’m currently wrestling with this same issue, and not sure the right way to handle it.

I have a system that automatically starts threads to do background computations. The idea is similar to futures (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/84317).

The trouble is that the various functions that are creating these futures might very well be used naïvely in a module of shared utility routines. It’s unreasonable for me to say to the users of the system “Oh, and by the way, you can’t do this.”

Anyway, is there any way to work around this? My own code does not import within functions, but a number of standard library calls *do*. (For example, os.execvp.)

Popular posts from this blog

Why schema definition belongs in the database

Earlier, I wrote about how ORM developers shouldn't try to re-invent SQL . It doesn't need to be done, and you're not likely to end up with an actual improvement. SQL may be designed by committee, but it's also been refined from thousands if not millions of man-years of database experience. The same applies to DDL. (Data Definition Langage -- the part of the SQL standard that deals with CREATE and ALTER.) Unfortunately, a number of Python ORMs are trying to replace DDL with a homegrown Python API. This is a Bad Thing. There are at least four reasons why: Standards compliance Completeness Maintainability Beauty Standards compliance SQL DDL is a standard. That means if you want something more sophisticated than Emacs, you can choose any of half a dozen modeling tools like ERwin or ER/Studio to generate and edit your DDL. The Python data definition APIs, by contrast, aren't even compatibile with other Python tools. You can't take a table definition

Python at Mozy.com

At my day job, I write code for a company called Berkeley Data Systems. (They found me through this blog, actually. It's been a good place to work.) Our first product is free online backup at mozy.com . Our second beta release was yesterday; the obvious problems have been fixed, so I feel reasonably good about blogging about it. Our back end, which is the most algorithmically complex part -- as opposed to fighting-Microsoft-APIs complex, as we have to in our desktop client -- is 90% in python with one C extension for speed. We (well, they, since I wasn't at the company at that point) initially chose Python for speed of development, and it's definitely fulfilled that expectation. (It's also lived up to its reputation for readability, in that the Python code has had 3 different developers -- in serial -- with very quick ramp-ups in each case. Python's succinctness and and one-obvious-way-to-do-it philosophy played a big part in this.) If you try it out, pleas

A review of 6 Python IDEs

(March 2006: you may also be interested the updated review I did for PyCon -- http://spyced.blogspot.com/2006/02/pycon-python-ide-review.html .) For September's meeting, the Utah Python User Group hosted an IDE shootout. 5 presenters reviewed 6 IDEs: PyDev 0.9.8.1 Eric3 3.7.1 Boa Constructor 0.4.4 BlackAdder 1.1 Komodo 3.1 Wing IDE 2.0.3 (The windows version was tested for all but Eric3, which was tested on Linux. Eric3 is based on Qt, which basically means you can't run it on Windows unless you've shelled out $$$ for a commerical Qt license, since there is no GPL version of Qt for Windows. Yes, there's Qt Free , but that's not exactly production-ready software.) Perhaps the most notable IDEs not included are SPE and DrPython. Alas, nobody had time to review these, but if you're looking for a free IDE perhaps you should include these in your search, because PyDev was the only one of the 3 free ones that we'd consider using. And if you aren