2011-12-18 23 views
7

Tôi không thể quyết định liệu deque sau có an toàn ren không.
Tóm lại, tôi đã tạo một lớp với một deque hiển thị nội dung của nó sau mỗi giây trong một chuỗi mới (vì vậy nó sẽ không tạm dừng chương trình chính trong khi in).
Các deque được điền từ các chủ đề chính, vì vậy về cơ bản có NÊN là một cơ hội va chạm.
BAO GIỜ, deque được điền bằng cách sử dụng một phương thức lớp, do đó về cơ bản nó được truy cập từ bên trong bản thân cá thể, do đó từ cùng một luồng.
Dưới đây là đoạn code đơn giản:Đây có phải là sợi chỉ an toàn trong python không?

import threading 
import time 
from collections import deque 

class MyQueue(threading.Thread): 
    def __init__(self): 
     threading.Thread.__init__(self) 
     self.q = deque() 
     self.start() 

    def run(self): 
     # pop out queue items every 1 sec 
     # (please ignore empty deque for now) 
     while True: 
      print self.q.popleft() 
      time.sleep(1) 

    def add_to_q(self, val): 
     # this function is called from outside 
     self.q.append(val) 

# main 
# fill the queue with values 
qu = MyQueue() 
for i in range(1:100): 
    qu.add_to_q(i) 

Vì vậy, mặc dù thêm và loại bỏ các mục từ hàng đợi diễn ra bên trong Ví dụ, có một nguy cơ do các chức năng bổ sung được gọi từ bên ngoài chẳng hạn?

CHỈNH SỬA:
Vì tôi cần phải sửa đổi các mục trong deque của mình, tôi phải sử dụng Deque. Những gì tôi làm là: roatate() đến mục đã cho, bật nó ra, sửa đổi, đẩy nó trở lại và xoay() nó trở lại vị trí ban đầu của nó. Trừ khi tôi tìm cách triển khai sửa đổi các mục trong Hàng đợi, tôi sẽ phải dán vào Deque

+2

Nếu bạn chỉ cần một hàng đợi thread-safe (tôi không thấy bạn sử dụng bất kỳ tính năng đặc trưng nào), bạn có thể sử dụng [hàng đợi an toàn trong luồng được tích hợp sẵn] (http://docs.python.org/library/queue.html). – delnan

+0

David, cảm ơn, tôi đã thêm vòng lặp. delnan, tôi đã loại trừ một số tính năng. Các deque đang được luân chuyển mỗi bây giờ và sau đó để các mục có thể được popped ra, sửa đổi, đẩy trở lại và quay trở lại vị trí ban đầu của họ. Tôi không tìm thấy cách nào để làm điều đó với Queue – user1102018

+6

Không thể viết mã để kiểm tra xem có gì đó là luồng an toàn không và thay vào đó bạn phải đọc tài liệu hoặc nghiên cứu mã nguồn. Thông thường, nếu một cái gì đó không phải là threadsafe nó sẽ vẫn làm việc gần như tất cả các thời gian trong một bối cảnh luồng và sau đó phát nổ tuần sau đó. –

Trả lời

13

Deque là an toàn chủ đề (http://docs.python.org/library/collections.html#deque-objects) để nối và bật từ các cạnh đối diện. Beneath here, các tài liệu chỉ đề cập rằng chắp thêm() và popleft() là chuỗi an toàn.

Có một quá trình triển khai chủ đề an toàn của chính Hàng đợi. Vì vậy, bạn nên sử dụng nó trừ khi bạn có một số yêu cầu lạ.

+4

Không chỉ là luồng an toàn, mà hiệu suất của nó còn cao hơn nhiều so với mô-đun Queue.Điều có giá trị mà module Queue thêm vào là 'get' có thể chặn. – amcnabb

+0

Chỉ có chủ đề an toàn nối và bật khi tôi đọc nó (ví dụ, bạn không nhất thiết có thể sử dụng 'len()' qua chủ đề có thể bạn?) –

+0

deque chắc chắn ném nếu bạn lặp lại và đẩy cùng một lúc – Brannon

2

Để biết thông tin có một vé Python tham chiếu cho deque thread-an toàn (https://bugs.python.org/issue15329).

Title "làm rõ những phương thức deque là thread-safe", mấu chốt là:

append của deque(), appendleft(), pop(), popleft(), và len (d) hoạt động là thread-safe trong CPython. Các phương thức chắp thêm có DECREF ở cuối (đối với trường hợp maxlen đã được thiết lập), nhưng xảy ra sau khi tất cả các cập nhật cấu trúc đã được thực hiện và các bất biến đã được khôi phục, vì vậy bạn có thể xử lý các hoạt động này như nguyên tử.

Dù sao, nếu bạn không chắc chắn 100% và bạn thích độ tin cậy trên hiệu suất, chỉ cần đặt một Khóa như cho print self.q.popleft()self.q.append(val);)

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