2011-12-18 29 views
7

मैं यह तय नहीं कर सकता कि निम्नलिखित डेक थ्रेड-सुरक्षित है या नहीं।
संक्षेप में, मैंने एक डेक के साथ एक कक्षा बनाई है जो प्रत्येक सामग्री को एक नए धागे में प्रदर्शित करता है (इसलिए यह प्रिंटिंग के दौरान मुख्य कार्यक्रम को रोक नहीं देगा)।
डेक मुख्य धागे से भरा हुआ है, इसलिए मूल रूप से टकराव का मौका होना चाहिए।
हालांकि, डेक एक वर्ग विधि का उपयोग करके भर जाता है, इसलिए अनिवार्य रूप से इसे उसी उदाहरण से ही उदाहरण के भीतर से एक्सेस किया जाता है।क्या यह डेक थ्रेड-पाइथन में सुरक्षित है?

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) 

तो, जोड़ने और कतार से आइटम उदाहरण के अंदर जगह ले दूर करने हालांकि, वहाँ एक जोखिम जोड़ने समारोह के कारण उदाहरण के बाहर से बुलाया जा रहा है:
यहाँ सरलीकृत कोड है?

संपादित करें:
चूंकि मुझे अपने डेक में आइटम संशोधित करने की आवश्यकता है, इसलिए मुझे डेक का उपयोग करना पड़ा। मैं क्या करता हूं: दिए गए आइटम पर roatate(), इसे पॉप आउट करें, संशोधित करें, इसे वापस धक्का दें और घुमाएं() इसे वापस अपनी मूल स्थिति में ले जाएं।
जब तक मैं एक कतार में संशोधित आइटम को लागू करने का एक तरीका मिल जाए, मैं Deque

+2

तुम सिर्फ एक धागा सुरक्षित कतार की जरूरत है (मुझे नहीं पता आपको किसी भी डेक-विशिष्ट विशेषताओं का उपयोग करके देखें), आपको शायद [अंतर्निहित थ्रेड-सुरक्षित कतार] (http://docs.python.org/library/queue.html) का उपयोग करना चाहिए। – delnan

+0

डेविड, धन्यवाद, मैंने लूप जोड़ा। डेलनान, मैंने कुछ विशेषताओं को छोड़ दिया। डेक को हर समय घुमाया जा रहा है और फिर वस्तुओं को पॉप आउट किया जा सकता है, संशोधित किया जा सकता है, वापस धकेल दिया जा सकता है और वापस अपनी मूल स्थिति में घुमाया जा सकता है। मुझे क्यूई – user1102018

+6

के साथ ऐसा करने का कोई तरीका नहीं मिला, अगर कुछ थ्रेडसेफ है तो परीक्षण करने के लिए कोड लिखना असंभव है और इसके बजाय आपको दस्तावेज़ को पढ़ना होगा या स्रोत कोड का अध्ययन करना होगा। अक्सर, अगर कुछ थ्रेडसेफ नहीं है तो यह अभी भी थ्रेड किए गए संदर्भ में लगभग हर समय काम करेगा और फिर सप्ताहों में विस्फोट करेगा। –

उत्तर

13

Deque पर कायम करना होगा संलग्न कर देता है के लिए धागा सुरक्षित (http://docs.python.org/library/collections.html#deque-objects) है और विपरीत दिशा से दिखाई नहीं देता। Beneath here, दस्तावेज़ केवल उल्लेख करते हैं कि संलग्न() और पॉपलफ्ट() थ्रेड-सुरक्षित हैं।

कतार के एक थ्रेड-सुरक्षित कार्यान्वयन है। इसलिए जब तक आपके पास कुछ अजीब आवश्यकताएं न हों तब तक इसका उपयोग करना चाहिए।

+4

न केवल डेक थ्रेडसेफ है, लेकिन यह प्रदर्शन कतार मॉड्यूल से काफी अधिक है।कतार मॉड्यूल जोड़ता है कि मूल्यवान बात यह है कि 'get' ब्लॉक कर सकते हैं। – amcnabb

+0

केवल थ्रेड सुरक्षित इसे जोड़ता है और पॉप करता है जैसा कि मैंने इसे पढ़ा है (उदाहरण के लिए, आप आवश्यक रूप से 'len() 'थ्रेड में उपयोग नहीं कर सकते हैं?) –

+0

डेक निश्चित रूप से फेंक देता है यदि आप एक ही समय में पुन: प्रयास करते हैं और धक्का देते हैं – Brannon

2

जानकारी के लिए वहाँ एक अजगर टिकट Deque धागे की सुरक्षा (https://bugs.python.org/issue15329) के लिए संदर्भित है।

शीर्षक "स्पष्ट जो Deque तरीकों धागा सुरक्षित हैं", लब्बोलुआब यह है:

Deque के संलग्न(), appendleft(), पॉप(), popleft(), और लेन (घ) ऑपरेशन सीपीथॉन में थ्रेड-सुरक्षित हैं। एपेंड विधियों में अंत में DECREF होता है (उन मामलों के लिए जहां मैक्सलेन सेट किया गया है), लेकिन यह सभी संरचना अद्यतन किए जाने के बाद होता है और इनवेरिएंट को पुनर्स्थापित कर दिया गया है, इसलिए इन परिचालनों का इलाज करना ठीक है परमाणु के रूप में।

वैसे भी, अगर आप 100% यकीन नहीं कर रहे हैं और आप प्रदर्शन से अधिक विश्वसनीयता को पसंद करते हैं, बस print self.q.popleft() और self.q.append(val) के लिए एक तरह बंद कर दिया;)