2010-08-23 26 views
19

Liệu luồng trăn có phơi bày các vấn đề về khả năng hiển thị bộ nhớ và câu lệnh sắp xếp lại như Java không? Vì tôi không thể tìm thấy bất kỳ tham chiếu đến một "Mô hình bộ nhớ Python" hoặc bất cứ điều gì như thế, mặc dù thực tế rằng rất nhiều người đang viết mã Python đa luồng, tôi đoán rằng những gotchas không tồn tại ở đây. Ví dụ: không có dễ bay hơi từ khóa. Nhưng nó dường như không được tuyên bố rõ ràng ở bất cứ nơi nào, ví dụ, một sự thay đổi trong một biến trong một chuỗi là ngay lập tức hiển thị cho tất cả các chủ đề khác.python luồng: mô hình bộ nhớ và khả năng hiển thị

Có lẽ công cụ này là tất cả đều rất rõ ràng đối với các lập trình viên Python, nhưng như một lập trình viên Java sợ hãi, tôi cần thêm một chút yên tâm :)

Trả lời

17

Có không có mô hình chính thức cho luồng của Python (hey, sau khi tất cả, không có một cho Java trong nhiều năm ... hy vọng, một trong những cũng cuối cùng sẽ được viết cho Python). Trong thực tế, không có triển khai Python thực hiện bất kỳ tối ưu hóa nâng cao nào như câu lệnh sắp xếp lại hoặc tạm thời xử lý các biến được chia sẻ dưới dạng biến cục bộ - và bạn có thể dựa vào những hạn chế ngữ nghĩa này mặc dù chúng không được đảm bảo chính thức.

CPython nói riêng, như đề cập của @ Rawheiser, sử dụng khóa thông dịch toàn cầu; triển khai khác (PyPy, IronPython, Jython, ...) không (vì vậy chúng có thể sử dụng nhiều lõi hiệu quả với mô hình luồng, trong khi CPython yêu cầu đa xử lý cho cùng một mục đích), vì vậy bạn không nên dựa vào đó nếu bạn muốn để viết mã di động trong suốt quá trình triển khai Python. (Vì vậy, bạn không nên dựa vào "nguyên tử" của các hoạt động chỉ xảy ra nguyên tử trong CPython vì GIL, chẳng hạn như truy cập từ điển - trong các triển khai Python khác, nhiều luồng có thể sửa đổi một dict cùng một lúc và gây ra lỗi trừ khi bạn bảo vệ dict bằng khóa hoặc tương tự).

+2

Ngay cả trong CPython, truy cập từ điển không phải là nguyên tử trong mọi trường hợp. Nếu hàm băm/so sánh của các khóa được viết bằng Python, GIL sẽ tạm thời được giải phóng giữa các opcodes khi các hàm đó đang thực thi. (Bạn có thể đã biết điều này, nhưng tôi cho rằng nó đáng giá cho những độc giả khác) –

+1

Cảm ơn bạn! Tôi đã dành cả buổi sáng để học về GIL. Rõ ràng (C) Python lập trình sẽ liên quan đến một cách khác nhau để xem xét các chủ đề hơn tôi đang sử dụng để. @Daniel Stutzbach: Tôi mới sử dụng Python và có thể đã bỏ qua thực tế đó. Cảm ơn bạn. – philo

+3

@philo, tóm tắt tình huống đa nhiệm cho CPython: các chủ đề sẽ giúp bạn chỉ khi bạn có I/O chờ đợi (bạn có thể ủy quyền cho một luồng) hoặc các hoạt động nặng được thực hiện trong phần mở rộng Python an toàn (chẳng hạn như 'numpy '). Nếu mục đích của bạn là sử dụng nhiều lõi cho các hoạt động liên kết CPU, được mã hóa bằng Python, hãy sử dụng 'multiprocessing' thay vì' threading'. –

1
+0

Điều này có liên quan gì đến câu hỏi này? – habnabit

+0

Điều này có nghĩa là không có nhiều công cụ đa chủ đề phải lo lắng vì chúng chỉ đơn luồng tất cả mọi thứ tại trình thông dịch. –

+0

@KevinKostlan không chính xác. GIL cho phép mã python tinh khiết, chạy trong một luồng tại một thời điểm. đó là một sai lầm phổ biến để nghĩ rằng python là một quá trình đơn luồng, nhưng nó sử dụng các chủ đề thực sự. có nghĩa là, sau đó mặc dù một khóa toàn cầu cho phép chỉ có một luồng để làm việc tại một thời điểm, nó thực sự là một đối số hợp lệ để đặt câu hỏi liệu gán vào bộ nhớ trong một luồng có được phản ánh trên các luồng khác hay không. btw, các hoạt động I/O như socket.send và vv đang nhận được vé miễn phí từ GIL - do đó có nhiều luồng chạy và làm việc cùng nhau – RoeeK

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