On Apr 16, 5:36 pm, "Jason" <[EMAIL PROTECTED]> wrote: > On Apr 16, 7:28 am, [EMAIL PROTECTED] wrote: > > > > > On Apr 16, 3:05 am, Paul Rubin <http://[EMAIL PROTECTED]> wrote: > > > > [EMAIL PROTECTED] writes: > > > > > Please, can you elaborate further, I'm not sure if I understood. > > > > Should I lock global variables i, j during the execution of run()? In > > > > that case I have to apologize, I showed rather simplified version of > > > > the actual problem I have - in fact changer() and run() will be a bit > > > > more complex thus executing a bit longer and perhaps causing a > > > > dead-lock. > > > > Put both variables into one shared object with a lock (see the docs for > > > threading.RLock()). Acquire the lock before modifying or reading the > > > variables, and release it afterwards. That is the traditional way. > > > Thanks for the reply! And at the same time, please bear with me. > > > If I understand correctly: when one thread acquires the lock, every > > other thread has to wait. If so, this is not exacly what I would like > > to have since the thread might take a bit longer to finish. > > > The reason why I try so hard to use local variables is that they are > > inherently thread-safe. So I don't even mind to copy changer() every > > time run() is called - run() has it's own local variables i, j, no one > > has to touch them except it's ("local") function changer(). But the > > problem is, I don't know how to propagate run()'s variables into > > changer() without declarating them as changer()'s arguments (it would > > be ok to append the declaration during run-time, though, if I only > > knew how). > > In Python, names are bound to objects. The parameter names passed to > a function *are not inherently thread safe*! Python parameters are > not passed-by-value. To show you what I mean: > > >>> spam = ["delicious"] > >>> def test(meal): > > ... global spam > ... if spam is meal: > ... print "Spam is the same object as meal" > ...>>> test(spam) > > Spam is the same object as meal > > (While the "global spam" statement is optional in this case, I wanted > to make it painfully obvious where the "spam" name in function test is > coming from.) > > It is thread-safe to rebind the name "meal" in the function test (ie, > meal = "Green eggs"). It is not thread-safe to mutate or modify the > object that meal is bound to. In the example given above, appending > data to the list, removing data, changing elements, and other > operations will cause potential race conditions across multiple > threads. > > Follow Paul's advice and get acquainted with the issues of concurrent > and threaded programming. Judicious locking will help avoid most race > conditions. If you don't want to keep other threads waiting, make a > copy of your data then release the data lock. > > Depending on the data, you can usually have multiple threads "reading" > the data, as long as no other threads write to the data while there > are any readers. A writer can be allowed to change the data, but only > if there are no readers and no other writers. (This is commonly known > as a read/write lock.) I didn't see a read/write lock in the Python > documentation with some casual browsing, but one can be implemented > from the existing thread locking mechanisms. > > Your description of what you want to do is rather vague, so I can't > get too specific. You've described how you want to do things, but I > don't know what you're trying to accomplish. Where possible, simplify > your design. > > --Jason
All I was trying to do, was to get rid of those 'k's in changer(): def change_i(k, arg): k[0] = arg def change_j(k, arg): k[1] = arg def changer(k): change_i(k, 'changed_i') change_j(k, 'changed_j') def run(i='', j=''): k = [i, j] changer(k) [i, j] = k return i, j print run() == ('changed_i', 'changed_j') Maybe I made a mistake, I should have asked this first, sorry. If the only way to accomplish this is through locks, then I guess I better use those 'k's, what do you think? Thanks Jason, thanks Paul! -- http://mail.python.org/mailman/listinfo/python-list