2012-02-08 35 views
3

從混亂重構我已經編輯了問題:線程和信息路過 - 如何

one.py

import threading 
count = 5 
dev = threading.Thread(name='dev', target=dev,args=(workQueue,count,)) 
dev.setDaemon(True) 
dev.start() 
workQueue = Queue.Queue(10) 
queueLock.acquire() 
workQueue.put(word) 
queueLock.release() 
count = 3 
time.sleep(2) 
count = 5 

但在這裏,我的困惑是,我能夠從隊列中提出,並得到價值在線程之間,但在計數的情況下,它不反映。

這是爲什麼?
什麼是實際上在這裏失蹤?

class dev (threading.Thread): 
    def test(self): 
     while 1: 
      print count 
      print self.EPP_Obj 
      queueLock.acquire() 
      if not self.workQueue.empty(): 
       data = self.workQueue.get() 
       print data 
       queueLock.release() 
      else: 
       queueLock.release() 

    def __init__(self, workQueue, EPP_Obj): 
     threading.Thread.__init__(self) 
     self.workQueue = workQueue 
     self.EPP_Obj = EPP_Obj 
+0

@all:我修改了一部分代碼..所以請忽略錯誤 – Ragav 2012-02-08 08:56:21

+0

您究竟在哪裏遇到問題?爲什麼開發類不是'Thread'子類?你在追蹤什麼[線程教程](http://www.google.com/search?q=python+threading+tutorial)?他們通常涵蓋你所要求的。 – 2012-02-08 09:07:07

+0

@ Rik Poggi:就像下面的代碼由阿諾德是我的需要,但我不想使用QUEUE機制來實現。只是想實現數據/對象通過線程lock.notify機制傳遞 – Ragav 2012-02-08 10:43:25

回答

5

讓我們先從一個例子:

Thread子類:

import threading 

class Dev(threading.Thread): 

    def __init__(self, workQueue, queueLock, count): 
     super(Dev, self).__init__() # super() will call Thread.__init__ for you 
     self.workQueue = workQueue 
     self.queueLock= queueLock 
     self.count = count 

    def run(self): # put inside run your loop 
     data = '' 
     while 1: 
      with self.queueLock: 
       if not self.workQueue.empty(): 
        data = self.workQueue.get() 
        print data 
        print self.count 

      if data == 'quit': 
       break 

with聲明是獲取和釋放鎖的智能方式,請看doc

現在運行的代碼:

​​

有了上面的代碼中,我們對如何self.count保持不變一個明顯的例子,無論我們做什麼count
這種行爲的原因是,美其名曰:

dev = Dev(work_q, q_lock, count) 

dev = Dev(work_q, q_lock, 1) 

是同樣的事情。

Arnold Moon告訴你一種方法來改變self.count。調整是我們的例子:

class Dev(threading.Thread): 

    def __init__(self, workQueue, queueLock, count): 
     super(Dev, self).__init__() 
     self.workQueue = workQueue 
     self.queueLock= queueLock 
     self.count = count 

    def set_count(self, value): 
     self.count = value 

    def run(self): 
     data = '' 
     while 1: 
      with self.queueLock: 
       if not self.workQueue.empty(): 
        data = self.workQueue.get() 
        print data 
        print self.count 

      if data == 'quit': 
       break 

調用set_count在我們運行的代碼將改變self.count值:

time.sleep(1) 
with q_lock: 
    work_q.put('word') 
# word 
# 1 

time.sleep(1) 
count = dev.count + 9 
dev.set_count(count) 
with q_lock: 
    work_q.put('dog') 
# dog 
# 10 

count = 'foo' 
with q_lock: 
    work_q.put('quit') 
# quit 
# 10 
dev.join() 

我希望這會幫助你澄清一些疑問。

+0

非常好的解釋,非常感謝:) – Bawn 2015-07-27 10:45:06

+0

是不是一個隊列線程安全的設計,因此鎖將是多餘的,而不是說一個列表或非線程安全? – RossGK 2017-11-28 18:21:17

3

我希望這會對你有幫助。我想你不知道你需要使用哪種方式。 有一些python中的多線程的方法。 我介紹一下使用類的方法。 你在代碼下面運行。你會明白的。

main.py

import stringRepeater 
import Queue 

workqueue = Queue.Queue() 
workqueue.put('test1') 
workqueue.put('test2') 
workqueue.put('test3') 

th = stringRepeater.stringRepeater(workqueue,5) 
th.start() 
print '----daemon is on ----' 
th.setCount(3) 
workqueue.put('test4') 
workqueue.put('test5') 

stringRepeater.py

import threading 

class stringRepeater(threading.Thread): 
    def __init__(self, workQueue, count): 
     threading.Thread.__init__(self) 
     self.workQueue = workQueue 
     self.repeatCount = count 

    def run(self): 
     while True: 
      teststring = self.workQueue.get() 
      for i in range(self.repeatCount): 
       print teststring 

    def setCount(self, newcount): 
     self.repeatCount = newcount 
+0

yes.i需要幾乎相同..但我需要它沒有隊列mechanism.is那可能 – Ragav 2012-02-08 10:36:30

+0

@Ragav你看我是如何通過__init __(self,workQueue,count)上的'count'對象: – 2012-02-08 11:08:46

+0

謝謝你的回覆.. __init __(self,workQueue,count)這裏count值是在我的線程啓動的第一次,但是當我嘗試它在調用htread之後改變計數值時它不起作用。但是在隊列能夠操作的情況下.. – Ragav 2012-02-08 11:46:34