2012-08-03 166 views
0

我對python隊列有疑問。如何知道隊列中的特定任務是否完成?

我寫了一個線程類,其run()方法執行隊列。

import threading 
    import Queue 

    def AThread(threading.Thread): 
    def __init__(self,arg1): 
     self.file_resource=arg1 
     threading.Thread.__init__(self) 
     self.queue=Queue.Queue() 

    def __myTask(self): 
     self.file_resource.write() 
     ''' Method that will access a common resource 
      Needs to be synchronized. 
      Returns a Boolean based on the outcome 
     ''' 

    def run(): 
     while True: 
      cmd=self.queue.get() 
      #cmd is actually a call to method 
      exec("self.__"+cmd) 
      self.queue.task_done() 


#The problem i have here is while invoking the thread 
a=AThread() 
a.queue.put("myTask()") 
print "Hai" 

AThread的相同實例(= AThread())將加載任務從不同的位置的隊列。

因此,底部的print語句應該等待通過上面的語句添加到隊列中的任務,並等待一個確定的時間段,並且還會收到執行任務後返回的值。

有沒有一種簡單的方法來實現這一目標?我已經搜索了很多關於此的內容,請仔細閱讀此代碼並提供建議。

爲什麼python的獲取和釋放鎖不在類的實例上。在上述場景中,AThread的實例a和b不需要同步,但是當應用獲取和釋放鎖定時,myTask對a和b的實例都同步運行。

請提供建議。

+1

爲什麼每個線程都有一個隊列? – RedBaron 2012-08-03 06:11:46

+0

我已經修改了代碼。這對於等待b = AThread(「b.txt」)的= Athread(「a.txt」)來說是不合適的,因爲它們對myTask方法的調用將在兩個不同的文件上進行。因此Athread(「a.txt」)只會被調用一次,其他所有對myTask的調用都會進入隊列。 – 2012-08-03 07:20:34

+0

很少使用線程,但通常隊列是全局的並且具有要完成的任務。有一個線程池(一個線程隊列),它擁有線程。一個線程管理器將循環直到任務隊列不爲空 - 它會喚醒,從task_queue中取出一個任務,從線程池中取出一個線程。將任務分配給線程。去睡覺。如果線程池中沒有線程,它將休眠並重試。線程本身 - 執行並返回結果後,將自己添加到線程池中。線程將獨立工作,但程序不會退出,直到完成所有任務。 – RedBaron 2012-08-03 07:33:43

回答

0

根據問題的特定輪廓,您可以採取很多方法。

如果您的print "Hai"只需在myTask完成後發生,您可以將其放入任務中,並在完成後讓myTask將該任務放入隊列中。 (如果你是一個CS理論的人,你可以把它看作是類似於延續傳球的風格)。

如果您的print "Hai"對多個任務有更精細的依賴性,您可以查看期貨或承諾。

你可以採取一步到基於Actor的併發的世界,在這種情況下,可能會有一個同步的消息發送方法,可以做或多或少的你想要的。

如果您不想使用期貨或承諾,您可以通過引入條件變量手動實現類似的事情。在myTask啓動之前設置條件變量並將其傳遞給myTask,然後等待它被清除。隨着程序的增長,您必須非常小心,並且不斷重新考慮您的鎖定策略,以確保它保持簡單和易於理解 - 這就是困難的併發錯誤。

想要得到你想要的最小明智步驟可能是提供一個阻塞版本的Queue.put(),它執行條件變量的事情。確保考慮是否要阻塞隊列爲空,或者直到隊列中的內容從隊列中刪除,或者直到隊列中的內容已經完成處理。然後確保你在思考時實施你決定實施的東西。

+0

我只是想知道,我從隊列中獲得的好處實際上是什麼。我覺得我可以通過Python列表實現這一點。如果有一個方法queue.iscomplete(task)return bool被提供,它可能會很有用。 – 2012-08-03 07:30:42

+0

線程如何獲取對python中的對象的鎖定? – 2012-08-03 08:01:09

+0

是queue.put()線程安全嗎?是list.append()?我不知道這些問題的答案,但如果第一個是肯定的,第二個是否定的,那麼這就是一個好處。另一個好處就是性能:當你向一端添加東西並從另一端取東西時,一個隊列應該表現良好,但是如果你使用了一個列表,那麼將會有大量的複製進行(移動所有現有的元素在插入時向前或在刪除時向後移動所有元素)。 – Iain 2012-08-03 10:24:41

相關問題