2013-06-10 2 views
0

파이썬 저장 프로세스 (폐쇄 파일 핸들러)

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_save() 처리하고 done_q의 모든 데이터를 저장하고 file_handler의 닫습니다 알 수있다 기본적인 예를 검토하세요?

답변

1

센티널 가치는 어떻습니까?

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() 

EDIT : 여러 작업자를 동기화하십시오.

+2

만약'None'이 유효한 데이터라면'END_OF_DATA = object()'를 사용하여 데이터가 실제 센티넬 값인 경우에만'data is END_OF_DATA'가 참임을 보장해야합니다. – Bakuriu

+0

Queue, Queue.get() 블록에 남아있는 항목이 없으면'data = q_in.get()'데이터는 None이 될 수 없습니다. – nacholibre

+0

@nacholibre 제작자 (queue_add, worker)가 None을 넣기 때문에 q_in.get()은 None이 될 수 있습니다. – falsetru