【问题标题】:Queue.put() method doesn't create output file needed (Python)Queue.put() 方法不创建所需的输出文件(Python)
【发布时间】:2016-11-29 06:48:24
【问题描述】:

我正在使用线程和队列在 python 中编写一个简单的凯撒密码程序。即使我的程序能够运行,它也不会创建必要的输出文件。将不胜感激任何帮助,谢谢!

我猜异常开始于我使用队列存储加密字符串的地方,这里:

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

【问题讨论】:

    标签: python file queue output caesar-cipher


    【解决方案1】:

    while not q1.full 永远不能是True,因为full 是一种方法,因此在布尔上下文中始终是True,因此not q1.full 将始终是False,您需要调用方法:q1.full()q2.full 也一样。

    此外,在这种情况下,您不应该尝试检测队列是否已满。如果它不完整,那么您将继续添加数据,直到它是然后忽略其余部分,或者您的 index 可以增加超过 data 的大小,您将继续添加 0 长度的数据块。

    您应该使用单独的线程来写入q1 和读取q2,然后您可以让q1 阻塞put()

    此外,您在工作线程中使用相同的锁来基本上序列化所有计算,这违背了线程的目的。您正在处理的问题是 CPU 限制,多线程不会为您在 python 中提供任何加速。看看multiprocessing 模块。使用multiprocessing.Pool.map()(或其他一些映射方法)可以显着简化整个程序,同时通过 mutliprocessig 加快速度。

    【讨论】:

    • 感谢您指出我的错误。我已经删除了我试图检测队列是否已满的部分。在你的第三句话中,我不太明白我应该如何实施你刚才所说的。 (顺便说一句,在删除检测条件后,我的程序仍然无法正常运行)。我应该打开两个线程吗?写线程和读线程?我也会尝试用多处理编写代码,谢谢推荐。
    • 你只需要一个额外的线程,例如用于写入队列并继续在主线程中读取(或相反)。此外,当您使用这种消费者-生产者模式时,返回结果的顺序与作业入队的顺序不同,但对于此类问题,您需要保留顺序。 Pool.map() 没有这个问题,因为它保持订单。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-08
    • 2017-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多