2008-10-17 12 views
12

में ऐसा लगता हैकीबोर्ड interruptable अवरुद्ध कतार अजगर

import Queue 

Queue.Queue().get(timeout=10) 

कुंजीपटल व्यवधान कारक (Ctrl-C) जबकि

import Queue 

Queue.Queue().get() 

है नहीं है। मैं हमेशा एक लूप बना सकता था;

import Queue 
q = Queue() 

while True: 
    try: 
     q.get(timeout=1000) 
    except Queue.Empty: 
     pass 

लेकिन यह करने के लिए एक अजीब बात की तरह लगता है।

तो, वहाँ एक अनिश्चित काल के लिए हो रही इंतजार कर रहे हैं, लेकिन कुंजीपटल व्यवधान कारक Queue.get() का एक तरीका है?

+0

धागा किसी भी अन्य तरीके से बाधित है? – fatuhoku

+3

यह [बग 1360] है (http://bugs.python.org/issue1360) जो "ठीक नहीं होगा" बंद हो गया। सुझाव वैकल्पिक हल यदि आप किसी रुकावट की जरूरत हमेशा एक समय समाप्ति निर्दिष्ट करने के लिए है। – dimo414

उत्तर

6

Queue ऑब्जेक्ट्स में यह व्यवहार है क्योंकि वे Condition ऑब्जेक्ट्स का उपयोग कर लॉक करते हैं threading मॉड्यूल। तो आपका समाधान वास्तव में जाने का एकमात्र तरीका है।

हालांकि, अगर आप वास्तव में है कि इस करता है एक Queue विधि चाहते हैं, आप Queue वर्ग monkeypatch कर सकते हैं। उदाहरण के लिए:

def interruptable_get(self): 
    while True: 
     try: 
      return self.get(timeout=1000) 
     except Queue.Empty: 
      pass 
Queue.interruptable_get = interruptable_get 

यह जाने हैं आप कहते हैं

q.interruptable_get() 
बजाय

interruptable_get(q) 

हालांकि monkeypatching आम तौर पर पायथन समुदाय द्वारा इस तरह के मामलों में, एक नियमित रूप से समारोह के बाद से हतोत्साहित किया जाता है उतना ही अच्छा लगता है।

+0

आह, मैं देख रहा हूँ, टपकाया कपोल-कल्पना * का एक बुरा मामले। ठीक है। * http://www.joelonsoftware.com/articles/LeakyAbstractions.html –

+0

क्यों बंदर बंदर की बजाय क्यूई उप-वर्ग नहीं है? –

+0

जब आप कतार ऑब्जेक्ट प्राप्त कर रहे हैं तो मोंकीपैचिंग बेहतर होती है जिसे तत्कालित किया जाता है और कुछ तृतीय-पक्ष कोड द्वारा लौटाया जाता है जिसे आप नहीं बदल सकते हैं, या संभवतः कुछ सहकर्मी के कोड द्वारा जिन्हें आप भी नहीं बदल सकते हैं। हालांकि, शायद मुझे उप-वर्गीकरण का उपयोग करना चाहिए क्योंकि शायद यह बहुत आम नहीं है। –

4

यह सब आपके उपयोग मामले पर लागू नहीं हो सकता। लेकिन मैं सफलतापूर्वक कई मामलों में इस पद्धति का उपयोग किया है: (अधूरे थे और संभावना गाड़ी है, लेकिन आप समझ गए होंगे)।

STOP = object() 

def consumer(q): 
    while True: 
     x = q.get() 
     if x is STOP: 
      return 
     consume(x) 

def main() 
    q = Queue() 
    c=threading.Thread(target=consumer,args=[q]) 

    try: 
     run_producer(q) 
    except KeybordInterrupt: 
     q.enqueue(STOP) 
    c.join()