2010-11-06 121 views
0

我怎樣才能更新不同線程之間的共享變量?python中的線程?python線程和共享變量

可以說我有5個線程工作在一個Queue.Queue()。隊列完成後,我想做其他操作,但我希望它只發生一次。

是否有可能共享和更新線程之間的變量。所以當Queue.empty()爲True時,這個事件被觸發,但如果其中一個線程正在做它,我不希望其他人也這樣做,因爲我會得到錯誤的結果。

編輯
我有一個反映文件系統上的文件的隊列。 文件上傳到網站的線程和每個線程正在上傳文件時,它更新了我從文件中獲得的關鍵字集()。
當隊列爲空時,我需要聯繫站點並告訴它更新關鍵字計數。現在每個線程都這樣做,我得到每個線程的更新是壞的。 我也嘗試清空設置,但它不起作用。

 keywordset = set() 
    hkeywordset = set() 
    def worker(): 
     while queue: 
      if queue.empty(): 
       if len(keywordset) or len(hkeywordset): 
        # as soon as the queue is empty we send the keywords and hkeywords to the 
        # imageapp so it can start updating 
        apiurl = update_cols_url 
        if apiurl[-1] != '/': 
         apiurl = apiurl+'/' 
        try: 
         keywords = [] 
         data = dict(keywords=list(keywordset), hkeywords=list(hkeywordset)) 
         post = dict(data=simplejson.dumps(data)) 
         post = urllib.urlencode(post) 
         urllib2.urlopen(apiurl, post) 
         hkeywordset.clear() 
         keywordset.clear() 
         print 'sent keywords and hkeywords to imageapp...' 
        except Exception, e: print e 
      # we get the task form the Queue and process the file based on the action 
      task = queue.get() 
      print str(task) 
      try: 
       reindex = task['reindex'] 
      except: 
       reindex = False 
      data = updater.process_file(task['filename'], task['action'], task['fnamechange'], reindex) 
      # we parse the images keywords and hkeywords and add them to the sets above for later 
      # processing 
      try: 
       for keyword in data['keywords']: 
        keywordset.add(keyword) 
      except: pass 
      try: 
       for hkw in data['hkeywords']: 
         hkeywordset.add(hkw) 
      except:pass 
      queue.task_done() 


    for i in range(num_worker_threads): 
     t = threading.Thread(target=worker) 
     t.daemon = True 
     t.start() 

    while 1: 
     line = raw_input('type \'q\' to stop filewatcher... or \'qq\' to force quit...\n').strip()

這就是我基本上想要的。但是當然queue.empty()的部分獲得的執行次數與我擁有的線程一樣多。

回答

0

如果您使用隊列來運行您的線程(thread pool),所以您要確保不會有競爭條件(線程安全),因爲隊列以順序方式運行您的線程,所以我認爲您可以在線程之間共享一個變量,你可以確定這個變量不會有競爭條件。

編輯:這是你想要做什麼,希望類似的事情這可以給你回答你的問題這時候:):

import Queue 
import threading 
import ftplib 
import os 


class SendFileThread(threading.Thread): 
    """ Thread that will handle sending files to the FTP server""" 

    # Make set of keywords a class variable. 
    Keywords = set() 

    def __init__(self, queue, conn): 

      self.conn = conn 
      self.queue = queue 

      threading.Thread.__init__(self) 

     def run(self): 
      while True: 
       # Grabs file from queue. 
       file_name = self.queue.get() 

       # Send file to FTP server. 
       f=open(file_name,'rb') 
       self.conn.storbinary('STOR '+os.path.basename(file_name),f) 

       # Suppose that this keywords are in the first line. 
       # Update the set of keywords. 
       SendFileThread.Keywords.update(f.readline().split(" "))) 

       # Signals to queue job is done. 
       self.queue.task_done() 


def main(): 
    # Files to send. 
    files = os.listdir('/tosend') 

    queue = Queue.Queue() 

    # Connect to the FTP server. 
    conn = ftplib.FTP('ftp_uri') 
    conn.login() 

    # Create 5 threads that will handle file to send. 
    for i in range(5): 
     t = SendFileThread(queue, conn) 
     t.start() 

    # Fill the queue with files to be send. 
    for file in files: 
     queue.put(file) 

    # Wait until or thread are finish 
    queue.join() 

    # Send the keywords to the FTP server. 
    # I didn't understand well the part update keywords count, 
    # how this count is stored ... 
    # Here i will just send the keywords to the FTP server. 
    with open("keywords", "w") as keywords_file 
     keywords_file.write(";".join(SendFileThread.Keywords)) 
     conn.storbinary('STOR '+os.path.basename("keywords"), 
          keywords_file) 

    conn.close() 


if __name__ == '__main__': 
    main() 
+0

抱歉,但我真的不明白你的意思。 – aschmid00 2010-11-06 21:56:05

+0

@ aschmid00:__sorry,但我真的不明白你的意思,這對我來說也是一樣的?我的意思是幫助,但我認爲,而我只是讓你更困惑,我想我會刪除這個答案,除非你給我們更多的細節,你想做什麼,也許一些代碼來了解更多的問題,希望你找到你的答案:) – mouad 2010-11-06 22:01:52

+0

謝謝!我會盡快嘗試並讓你知道。 – aschmid00 2010-11-07 14:20:04

0

爲什麼你就不能添加的最後一步隊列 ?

+0

多數民衆贊成什麼即時嘗試與空()我在哪裏處理數據集()並做最後的測試。問題是,如果我有多個線程,這個最後一步是爲每個線程處理一次。我希望它只發生一次。 – aschmid00 2010-12-08 13:09:58

0

在第一個隊列爲空之後放置此事件的另一個隊列。
或者有特別的線程可以參加這個活動。