multithreading - Odd threading behavior in python -


i have problem need pass index of array function define inline. function gets passed parameter function call callback.

the thing is, when code gets called, value of index wrong. solved creating ugly workaround interested in understanding happening here. created minimal example demonstrate problem:

from __future__ import print_function import threading   def works_as_expected():     in range(10):         run_in_thread(lambda: print('the number is: {}'.format(i)))  def not_as_expected():     in range(10):         run_later_in_thread(lambda: print('the number is: {}'.format(i)))  def run_in_thread(f):     threading.thread(target=f).start()  threads_to_run_later = [] def run_later_in_thread(f):     threads_to_run_later.append(threading.thread(target=f))   print('this works expected:\n') works_as_expected()  print('\nthis not work expected:\n') not_as_expected() t in threads_to_run_later: t.start() 

here output:

this works expected:  number is: 0 number is: 1 number is: 2 number is: 3 number is: 4 number is: 6 number is: 7 number is: 7 number is: 8 number is: 9  not work expected:  number is: 9 number is: 9 number is: 9 number is: 9 number is: 9 number is: 9 number is: 9 number is: 9 number is: 9 number is: 9 

can explain happening here? assume has enclosing scope or something, answer reference explains dark (to me) corner of python scoping valuable me.

i'm running on python 2.7.11

this result of how closures , scopes work in python.

what happening i bound within scope of not_as_expected function. though you're feeding lambda function thread, variable it's using being shared between each lambda , each thread.

consider example:

def make_function():     = 1     def inside_function():         print     = 2     return inside_function  f = make_function() f() 

what number think print? i = 1 before function defined or i = 2 after?

it's going print current value of i (i.e. 2). doesn't matter value of i when function made, it's going use current value. same thing happening lambda functions.

even in expected results can see didn't work right, skipped 5 , displayed 7 twice. happening in case each lambda usually running before loop gets next iteration. in cases (like 5) loop manages through 2 iterations before control passed 1 of other threads, , i increments twice , number skipped. in other cases (like 7) 2 threads manage run while loop still in same iteration , since i doesn't change between 2 threads, same value gets printed.

if instead did this:

def function_maker(i):     return lambda: print('the number is: {}'.format(i))  def not_as_expected():     in range(10):         run_later_in_thread(function_maker(i)) 

the i variable gets bound inside function_maker along lambda function. each lambda function referencing different variable, , work expected.


Comments

Popular posts from this blog

Delphi XE2 Indy10 udp client-server interchange using SendBuffer-ReceiveBuffer -

Qt ActiveX WMI QAxBase::dynamicCallHelper: ItemIndex(int): No such property in -

Enable autocomplete or intellisense in Atom editor for PHP -