Trong một hàm:
a += 1
sẽ được trình biên dịch giải thích là assign to a => Create local variable a
, đó không phải là điều bạn muốn. Nó có thể sẽ không thành công với một a not initialized
lỗi vì (cục bộ) a thực sự chưa được khởi tạo:
>>> a = 1
>>> def f():
... a += 1
...
>>> f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in f
UnboundLocalError: local variable 'a' referenced before assignment
Bạn có thể đạt được những gì bạn muốn với từ khóa (rất khó chịu và vì lý do chính đáng) global
, như vậy:
>>> def f():
... global a
... a += 1
...
>>> a
1
>>> f()
>>> a
2
Tuy nhiên, nói chung, bạn nên tránh sử dụng các biến toàn cục trở nên quá nhanh chóng. Và điều này đặc biệt đúng với các chương trình đa luồng, nơi bạn không có bất kỳ cơ chế đồng bộ hóa nào thread1
để biết khi nào a
đã được sửa đổi. Tóm lại: các luồng rất phức tạp và bạn không thể mong đợi có được sự hiểu biết trực quan về thứ tự các sự kiện đang xảy ra khi hai (hoặc nhiều) luồng hoạt động trên cùng một giá trị. Ngôn ngữ, trình biên dịch, hệ điều hành, bộ xử lý ... TẤT CẢ đều có thể đóng một vai trò nào đó và quyết định thay đổi thứ tự hoạt động vì tốc độ, tính thực tế hoặc bất kỳ lý do nào khác.
Cách thích hợp cho loại điều này là sử dụng các công cụ chia sẻ Python ( khóa
và bạn bè), hoặc tốt hơn, giao tiếp dữ liệu qua Hàng đợi thay vì chia sẻ nó, ví dụ như thế này:
from threading import Thread
from queue import Queue
import time
def thread1(threadname, q):
while True:
a = q.get()
if a is None: return
print a
def thread2(threadname, q):
a = 0
for _ in xrange(10):
a += 1
q.put(a)
time.sleep(1)
q.put(None)
queue = Queue()
thread1 = Thread( target=thread1, args=("Thread-1", queue) )
thread2 = Thread( target=thread2, args=("Thread-2", queue) )
thread1.start()
thread2.start()
thread1.join()
thread2.join()