2016-11-29 73 views
1

我寫在使用Python線程和隊列一個簡單的凱撒密碼的程序。即使我的程序能夠運行,它也不會創建必要的輸出文件。希望有任何幫助,謝謝!Queue.put()方法不創建輸出文件需要(蟒蛇)

我猜,我使用隊列來存儲加密的字符串異常開始,在這裏:

for i in range(0,len(data),l): 
    while not q1.full: 
     q1.put(data[index:index+l]) 
     index+=l 
    while not q2.empty: 
     output_file.write(q2.get()) 

這裏是整個代碼:

import threading 
import sys 
import Queue 
import string 

#argumanlarin alinmasi 
if len(sys.argv)!=4: 
    print("Duzgun giriniz: '<filename>.py s n l'") 
    sys.exit(0) 
else: 
    s=int(sys.argv[1]) 
    n=int(sys.argv[2]) 
    l=int(sys.argv[3]) 

#Global 
index = 0 

#kuyruk deklarasyonu 
q1 = Queue.Queue(n) 
q2 = Queue.Queue(2000) 

lock = threading.Lock() 

#Threadler 
threads=[] 

#dosyayi okuyarak stringe cevirme 
myfile=open('metin.txt','r') 
data=myfile.read() 

#Thread tanimlamasi 
class WorkingThread(threading.Thread): 
    def __init__(self): 
     threading.Thread.__init__(self) 

    def run(self): 
     lock.acquire() 
     q2.put(self.caesar(q1.get(), s)) 
     lock.release() 

    def caesar(self, plaintext, shift): 
     alphabet = string.ascii_lowercase 
     shifted_alphabet = alphabet[shift:] + alphabet[:shift] 
     table = string.maketrans(alphabet, shifted_alphabet) 
     return plaintext.translate(table) 

for i in range(0,n): 
    current_thread = WorkingThread() 
    current_thread.start() 
    threads.append(current_thread) 

output_file=open("crypted"+ "_"+ str(s)+"_"+str(n)+"_"+str(l)+".txt", "w") 

for i in range(0,len(data),l): 
    while not q1.full: 
     q1.put(data[index:index+l]) 
     index+=l 
    while not q2.empty: 
     output_file.write(q2.get()) 

for i in range(0,n): 
    threads[i].join() 

output_file.close() 
myfile.close() 

回答

0

while not q1.full永遠不能True,如full是一種方法,因此總是會True在布爾上下文,因此not q1.full永遠是False,則需要電話方法:q1.full()q2.full相同。

此外,您should'n嘗試檢測wheather隊列已滿在這種情況下。如果它是不飽滿,那麼你會continut添加數據,直到它再忽略其他,或者您可以index增加超過的data大小,你會繼續添加長度爲0的數據塊。

你應該使用一個單獨的線程用於寫入q1並從q2閱讀,那麼你可以只讓上put()q1塊。

而且,你用你的工作線程相同的鎖,基本序列化所有的計算,這違背了線程的目的。你正在處理的問題是CPU綁定,因爲多線程不會給你python中的任何加速。看看multiprocessing模塊。使用multiprocessing.Pool.map()(或其他一些地圖方法),整個程序可以大大簡化,並通過mutliprocessig同時加快速度。

+0

感謝您指出我的錯誤。我已經刪除了我試圖檢測隊列是否已滿的部分。 在你的第三句話,我並沒有完全得到我應該如何實現你剛纔說的。 (順便說一下,在刪除檢測條件後,我的程序仍然無法正常工作)。我應該打開兩個線程;書寫線程和Readthread? 我會盡量多處理以及編寫代碼,感謝您的建議。 –

+0

您只需要一個額外的線程,例如用於寫入隊列並繼續閱讀主線程(或其他方式)。此外,當您使用這樣的消費者 - 生產者模式時,返回結果的順序與作業排隊的順序不同,但對於此類問題,您需要保留訂單。 'Pool.map()'沒有這個問題,因爲它保持順序。 – mata