2011-01-20 33 views
6

Tôi đã đọc về GIL và nó không bao giờ thực sự xác định nếu điều này bao gồm các chủ đề chính hay không (tôi giả sử như vậy). Lý do tôi hỏi là bởi vì tôi có một chương trình với các chủ đề thiết lập sửa đổi một từ điển. Các chủ đề chính thêm/xóa dựa trên đầu vào của người chơi trong khi một luồng lặp dữ liệu cập nhật và thay đổi dữ liệu.Threading Python và GIL

Tuy nhiên trong một số trường hợp, một chuỗi có thể lặp qua các phím từ điển mà người ta có thể xóa chúng. Nếu có một cái gọi là GIL và chúng được chạy tuần tự, tại sao tôi nhận được lỗi dict thay đổi? Nếu chỉ có một giả sử để chạy tại một thời điểm, sau đó về mặt kỹ thuật điều này không nên xảy ra.

Có ai có thể làm sáng tỏ điều đó không? Cảm ơn bạn.

+2

Nói chung, việc tạo luồng Python chỉ có ý nghĩa đối với các chuỗi I/O-bound. Nếu bạn muốn thống nhất truy cập cấu trúc dữ liệu song song, bạn cần khóa rõ ràng. Nếu bạn cần song song với CPU, thường thì bạn phải sử dụng một cái gì đó hoàn toàn khác. – 9000

Trả lời

4

Khóa GIL ở cấp mã byte Python và áp dụng cho tất cả các chuỗi, ngay cả chuỗi chính. Nếu bạn có một chủ đề sửa đổi từ điển và một khóa lặp khác, chúng sẽ can thiệp lẫn nhau.

"Chỉ một lần chạy một lần" là đúng, nhưng bạn phải hiểu đơn vị chi tiết. Trong trường hợp GIL của CPython, mức độ chi tiết là một lệnh bytecode, vì vậy việc thực thi có thể chuyển đổi giữa các luồng tại bất kỳ bytecode nào.

+0

từ trang thuật ngữ Python 'GIL Cơ chế được trình thông dịch CPython sử dụng để đảm bảo rằng chỉ có một luồng thực thi mã byte bytecode tại một thời điểm. Điều này đơn giản hóa việc thực hiện CPython bằng cách làm cho mô hình đối tượng (bao gồm các kiểu dựng sẵn quan trọng như dict) ẩn hoàn toàn an toàn đối với truy cập đồng thời.' Nếu tôi không sai, điều này có nghĩa dict là luồng an toàn? – boh

+1

Nó phụ thuộc vào các hoạt động bạn thực hiện trên dict. Đây không phải là chủ đề an toàn: 'd [k] + = 1'. Khi nghi ngờ, hãy sử dụng đồng bộ hóa của riêng bạn. –

10

Chúng là chạy cùng một lúc, chúng chỉ không thi hành cùng một lúc. Các lần lặp lại có thể được xen kẽ. Trích dẫn Python:

Cơ chế sử dụng bởi các thông dịch viên CPython để đảm bảo rằng chỉ có một thread thực hiện Python bytecode tại một thời điểm.

Vì vậy, hai vòng for có thể chạy cùng một lúc, sẽ không có (ví dụ) hai số del dict[index] cùng một lúc.

+0

Ah cảm ơn, điều này có ý nghĩa với tôi. – Charles

+1

Sau đó, bạn nên đánh dấu câu trả lời là được chấp nhận :) –

3

Gil ngăn hai chủ đề sửa đổi trạng thái thông dịch đồng thời. Nó không cung cấp bất kỳ ràng buộc nhất quán luồng nào, hoặc bất kỳ loại mutex nào cả trên mức độ chi tiết nhỏ hơn toàn bộ quá trình. Nếu bạn cần phải đọc và sửa đổi một dict trong hai chủ đề, bạn nên sử dụng một mutex

1

Các lệnh chuyển đổi Python thường xuyên hơn bạn nghĩ. Bạn nói "chỉ có một" được cho là chạy cùng một lúc, và về mặt kỹ thuật đó là sự thật, nhưng nó phụ thuộc vào định nghĩa của bạn về "một". Các hoạt động nguyên tử của Python rất nhỏ. Ví dụ: thêm một mục vào một từ điển. Lặp lại toàn bộ từ điển có thể bị gián đoạn.

Bạn nên sử dụng đối tượng khóa từ thư viện threading để tách biệt các hoạt động nguyên tử của chương trình.

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