【问题标题】:Perform asynchronous tasks via subprocess without thread blocking通过子进程执行异步任务,无需线程阻塞
【发布时间】:2018-04-16 03:03:31
【问题描述】:

我的代码的目的是通过 tkinter 生成一个进度条,虽然我的进度条正在取得进展,但我想通过调用 7-zip 的子进程提取一个 .7z 文件。

解压 7-Zip 文件后,我想关闭计算机。这样做的第一个问题是,提取 7-Zip 文件的行之后的代码行,无需等待即可执行并关闭计算机。

鉴于此,我需要等到提取完成后再继续。与此有关的第 22 个问题是我无法阻止任何线程,因为我的进度条仍在运行。使用我当前的代码,我可以等待提取,但是在提取完成之前不会出现进度条,因为所有线程都被阻塞了。

从某种意义上说,我如何异步实现我的目标?

这是我的进度条码:

class FinishSetup(tk.Toplevel):

    # progress bar to simulate finishing set up
    def __init__(self, *args, **kwargs):
        tk.Toplevel.__init__(self, *args, **kwargs)
        self.progress = ttk.Progressbar(self, orient="horizontal",
            length=200, mode="determinate")
        self.progress.pack()

        self.bytes = 0
        self.maxbytes = 0

        self.size_top()

    def start(self):
        self.progress["value"] = 0
        self.maxbytes = 100000
        self.progress["maximum"] = 100000
        self.read_bytes()

    def read_bytes(self):
        self.bytes += 100
        self.progress["value"] = self.bytes
        if self.bytes < self.maxbytes:
            # read more bytes after 100 ms
            self.after(100, self.read_bytes)

    def size_top(self):
        self.resizable(width=False, height=False)

        ws = self.winfo_screenwidth()
        hs = self.winfo_screenheight()

        w = 200
        h = 22

        x = (ws/2) - (w/2)
        y = (hs/2) - (h/2)

        self.geometry('%dx%d+%d+%d' % (w, h, x, y))

        self.protocol("WM_DELETE_WINDOW", self.iconify)
        self.lift()
        self.attributes('-topmost', 'true')
        self.overrideredirect(True)

还有我提取 7-Zip 文件的主要代码:

archive_name = 'files.7z'
maps_dir = 'output'

extract = subprocess.Popen('"C:\\Program Files\\7-Zip\\7z.exe" x ' + archive_name + ' -o' + maps_dir, stdout=subprocess.PIPE)

for line in iter(extract.stdout.readline,''):
    print(line.rstrip())

print('Finished')

我需要能够运行我的进度条FinishSetup().start(),同时解压我的 7-Zip 文件,然后关闭我的计算机。

我一整天都在努力解决这个问题,但我意识到这可能是不可能的。

请告诉我你的想法,如果还有什么我应该尝试的。

【问题讨论】:

  • 这应该是可能的,但您需要考虑的是 tkinter 在应用程序中不能很好地使用多线程。并不是说不可能,只是你编程不会很有趣,神速勇敢的灵魂。

标签: multithreading python-2.7 asynchronous tkinter subprocess


【解决方案1】:

解决方案是在单独的线程或进程中进行提取。第二个线程或进程可以通过队列与 GUI 进行通信。您可以在 GUI 端轮询队列,使用after 不断重新调度每隔几百毫秒检查一次队列的函数。

【讨论】:

    猜你喜欢
    • 2017-07-07
    • 1970-01-01
    • 1970-01-01
    • 2016-12-16
    • 1970-01-01
    • 2021-06-15
    • 1970-01-01
    • 1970-01-01
    • 2011-05-07
    相关资源
    最近更新 更多