Python保存过程(关闭文件处理程序)
请回顾这个基本示例Python保存过程(关闭文件处理程序),python,multithreading,queue,Python,Multithreading,Queue,请回顾这个基本示例 def queue_add(): #this will exit when all lines from the #file are added in the Queue with open('get_from.txt') as f: for line in f: q.add(line.strip()) def queue_save(): #when to trigger save_to.close(
def queue_add():
#this will exit when all lines from the
#file are added in the Queue
with open('get_from.txt') as f:
for line in f:
q.add(line.strip())
def queue_save():
#when to trigger save_to.close()?!?!
save_to = open('save_to.txt')
while True:
data = q.get() #this functions blocks if `q` is empty, so how to know
#when to close the file handler `save_to`??
save_to.write(data)
def worker():
#this is daemon process
while True:
#work with file from
get = q.get()
#work with data
q_done.put('processed data')
q.task_done()
q = Queue()
q_done = Queue()
#starts the processes here..
因此,我的问题是如何知道
queue\u save()
已经处理并保存了来自done\u q的所有数据,并关闭它的文件处理程序?使用sentinel值如何
import Queue
import threading
END_OF_DATA = object() # sentinel
def queue_add(q):
with open('get_from.txt') as f:
for line in f:
q.put(line.strip())
def process(x):
# dummy
return str(len(x)) + '\n'
def worker(q_in, q_out):
while True:
data = q_in.get()
if data is END_OF_DATA:
break
q_out.put(process(data))
q_in.task_done()
def queue_save(q):
save_to = open('save_to.txt', 'w')
while True:
data = q.get()
if data is END_OF_DATA:
break
save_to.write(data)
q.task_done()
save_to.close()
q1 = Queue.Queue()
q2 = Queue.Queue()
n_workers = 4
t1 = threading.Thread(target=queue_add, args=(q1,))
workers = [
threading.Thread(target=worker, args=(q1, q2,))
for i in range(n_workers)
]
t3 = threading.Thread(target=queue_save, args=(q2,))
t1.start()
for worker in workers: worker.start()
t3.start()
t1.join()
q1.join()
for worker in workers: q1.put(END_OF_DATA)
for worker in workers: worker.join()
q2.join()
q2.put(END_OF_DATA)
t3.join()
编辑:同步多个工作进程。如果
无
是有效数据,则应使用结束数据=对象()
,这保证数据是结束数据
如果且仅当数据确实是前哨值时才为真。数据=q_in.get()
数据不能为无,如果队列中没有任何项目,Queue.get()阻塞。@nacholibre q_in.get()可以是None,因为生产者(Queue_add,worker)将None放置为0。+1表示_DATA=object()的END_。基本上,您可以通过这种方式发送命令,而不需要单独的通道。问题是如何使用相同的方法(可能是全局变量)同步多个worker?