Привет
Наткнулся на странное, а точнее непонятное мне, поведение при запуске потока.
Почему из приведенных трех примеров, способ запуска потока (пример 1), где потоки добавлялись в список и аргумент передавался в метод сразу, а не через kwargs, работает не так как ожидается? При этом, если использовать вместо списка словарь, то: при итерации по словарю через items код работает ожидаемо (пример 2), а если итерироваться с помощью values (пример 3), то работает аналогично примеру 1 - т.е., не так как ожидалось.
# Общий код
import threading
def print_i(i):
print(i)
Пример 1
threads = []
for i in range(2):
threads.append(threading.Thread(target=lambda: print_i(i)))
for t in threads:
t.start()
# Вывод в консоль:
1
1
Пример 2
threads = dict()
for i in range(2):
threads[i] = threading.Thread(target=lambda: print_i(i))
for i, t in threads.items():
t.start()
# Вывод в консоль:
0
1
Пример 3
threads = dict()
for i in range(2):
threads[i] = threading.Thread(target=lambda: print_i(i))
for t in threads.values():
t.start()
# Вывод в консоль:
1
1
Пример 4 (просто корректный способ запуска с передачей аргументов в Thread(**kwargs), который работает ожидаемо
threads = []
for i in range(2):
threads.append(threading.Thread(target=print_i, kwargs={'i':i}))
for t in threads:
t.start()
# Вывод в консоль:
0
1
Мне больше даже интересно, связано ли это именно с потоками или может это какая-то особенность самих структур данных?
UPD:
это как-то связано с пространством имен в потоках?
вот пример номер 5 в котором все имена уникальны, то получим опять те самые две единицы
import threading
def print_i(arg):
print(arg)
threads = dict()
for i in range(2):
threads[i] = threading.Thread(target=lambda: print_i(i))
for x, t in threads.items():
t.start()