Если у меня есть целое число i
, небезопасно делать i += 1
для нескольких потоков:
>>> i = 0
>>> def increment_i():
... global i
... for j in range(1000): i += 1
...
>>> threads = [threading.Thread(target=increment_i) for j in range(10)]
>>> for thread in threads: thread.start()
...
>>> for thread in threads: thread.join()
...
>>> i
4858 # Not 10000
Однако, если у меня есть список l
, кажется, что безопасно делать l += [1]
для нескольких потоков:
>>> l = []
>>> def extend_l():
... global l
... for j in range(1000): l += [1]
...
>>> threads = [threading.Thread(target=extend_l) for j in range(10)]
>>> for thread in threads: thread.start()
...
>>> for thread in threads: thread.join()
...
>>> len(l)
10000
Является l += [1]
гарантированным потокобезопасность? Если да, применимо ли это ко всем реализациям Python или просто к CPython?
Изменить: Кажется, что l += [1]
является потокобезопасным, но l = l + [1]
не...
>>> l = []
>>> def extend_l():
... global l
... for j in range(1000): l = l + [1]
...
>>> threads = [threading.Thread(target=extend_l) for j in range(10)]
>>> for thread in threads: thread.start()
...
>>> for thread in threads: thread.join()
...
>>> len(l)
3305 # Not 10000