yield, curry, mix-in, new.function, global, closure, .... what will work?

ecir.hana at gmail.com ecir.hana at gmail.com
Mon Apr 16 13:05:27 EDT 2007


On Apr 16, 5:36 pm, "Jason" <tenax.racc... at gmail.com> wrote:
> On Apr 16, 7:28 am, ecir.h... at gmail.com wrote:
>
>
>
> > On Apr 16, 3:05 am, Paul Rubin <http://phr...@NOSPAM.invalid> wrote:
>
> > > ecir.h... at gmail.com 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!




More information about the Python-list mailing list