如何在python中使用不同的threading.Thread更新共享变量?
假设我有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 :(得分: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()
答案 1 :(得分:0)
为什么不能将最后一步添加到队列中?
答案 2 :(得分:0)
在第一个队列为空之后,有另一个队列来放置此事件 或者对此活动有特殊的线索。