It's a good idea to try to find a concurrency model at a higher level of abstraction than locks and semaphores that fits the desired semantics and behaviour of your program, and use that to manage the interactions between threads.
I wrote some Python code implementing a number of useful concurrency primitives - multiqueues, reader-writer locks, active objects, dataflow variables and so on. It's available as part of the Tripoli triple space source code:
Incidentally, my own comments on (inter alia) Twisted's programming model and threads are here:
Unsurprisingly this little rant annoyed some Twisted people mightily; but Glyph's reply, in the comments on the post, is both polite and pertinent.