2012-06-19 50 views
5

Tôi có các chủ đề khác nhau và sau khi xử lý chúng đưa dữ liệu vào một danh sách chung. Có bất cứ điều gì được xây dựng trong python cho một danh sách hoặc một mảng numpy để được truy cập bởi chỉ có một chủ đề duy nhất. Thứ hai, nếu nó không phải là một cách thanh lịch để làm điều đó là gì?Làm thế nào để đồng bộ hóa danh sách python?

Trả lời

4

threading cung cấp Lock đối tượng nếu bạn cần bảo vệ toàn bộ phần quan trọng hoặc mô-đun Queue cung cấp hàng đợi an toàn.

4

Theo Thread synchronisation mechanisms in Python, đọc một mục duy nhất từ ​​danh sách và sửa đổi danh sách tại chỗ được đảm bảo là nguyên tử. Nếu đây là đúng (mặc dù nó có vẻ là mâu thuẫn với một phần bởi sự tồn tại của các mô-đun Queue), sau đó nếu mã của bạn là tất cả các hình thức:

try: 
    val = mylist.pop() 
except IndexError: 
    # wait for a while or exit 
else: 
    # process val 

Và tất cả mọi thứ đưa vào mylist được thực hiện bằng .append(), sau đó mã của bạn đã được an toàn. Nếu bạn không tin tưởng một tài liệu về điểm số đó, hãy sử dụng queue.queue, tất cả sẽ đồng bộ hóa cho bạn và có API tốt hơn list cho các chương trình đồng thời - đặc biệt, nó cung cấp cho bạn tùy chọn chặn vô thời hạn hoặc hết thời gian chờ , chờ .pop() hoạt động nếu bạn không có bất kỳ thứ gì khác mà chuỗi có thể đang tiếp tục trong thời gian chờ đợi.

Đối với mảng NumPy, và nói chung mọi trường hợp, nơi bạn cần nhiều hơn một hàng đợi nhà sản xuất/tiêu dùng, sử dụng một Lock hoặc RLock từ threading - đây thực hiện các giao thức quản lý bối cảnh, vì vậy việc sử dụng chúng là khá đơn giản:

with mylock: 
    # Process as necessarry 

Và python sẽ đảm bảo rằng khóa được giải phóng khi bạn rơi khỏi phần cuối của khối with - bao gồm cả trong các trường hợp phức tạp như nếu bạn làm một ngoại lệ.

Cuối cùng, xem xét liệu multiprocessing phù hợp hơn với ứng dụng của bạn hơn threading - chuỗi trong Python không được đảm bảo thực sự chạy đồng thời và trong CPython chỉ có thể nếu thả xuống mã cấp C. multiprocessing được xung quanh vấn đề đó, nhưng có thể có một số chi phí phụ - nếu bạn chưa có, bạn nên đọc các tài liệu để xác định cái nào phù hợp với nhu cầu của bạn tốt hơn.

+0

là 'mylist.pop (0)' cũng có tính chất atmoic? – willsteel

+0

Cảm ơn lời nhắc 'with mylock:'. Imho RLocks được sử dụng theo cách đó thường là thành ngữ rõ ràng nhất để bảo vệ các phần quan trọng trong lập trình hướng đối tượng. – jjmontes

+0

@willsteel cho câu trả lời dứt khoát, tôi khuyên bạn nên xem mã nguồn Python để biết danh sách được triển khai như thế nào, nhưng tôi sẽ * tưởng tượng rằng 'mylist.pop (0)' sẽ là nguyên tử nếu 'mylist.pop()' là (mà tôi cũng không thể trả lời dứt khoát, đó là lý do tại sao tôi cũng đề cập đến các phương thức đồng bộ hóa khác; nó cũng có thể thay đổi qua việc triển khai Python). Đặc biệt, tất cả các mã cấp C trong CPython * có thể * được bảo vệ bởi GIL (nhưng có tùy chọn để giải phóng nó). 'pop' (có lẽ) hoặc là giải phóng GIL hay không, bất chấp đối số của nó. – lvc

Các vấn đề liên quan