【问题标题】:Multiprocessing - tkinter pipeline communication多处理 - tkinter 管道通信
【发布时间】:2017-03-17 08:45:43
【问题描述】:

我有一个关于多处理和 tkinter 的问题。我在让我的进程与 tkinter GUI 并行运行时遇到了一些问题。我创建了一个简单的示例来练习,并且一直在阅读以了解多处理的基础知识。但是,当将它们应用于 tkinter 时,当时只运行一个进程。 (Using Multiprocessing module for updating Tkinter GUI) 另外,当我添加队列以在进程之间进行通信时,(How to use multiprocessing queue in Python?),进程甚至都不会启动。

目标: 我想要一个进程倒计时并将值放入队列中,一个在 1 秒后更新 tkinter 并向我显示值。

感谢所有建议

亲切的问候, S

编辑:我希望在调用 after 方法时数据可用。所以问题不在于 after 函数,而在于 after 函数调用的方法。每次完成计算需要 0.5 秒。因此,GUI 每秒无响应半秒。

EDIT2:已根据反馈对代码进行了更正,但此代码尚未运行。

class Countdown(): 
    """Countdown prior to changing the settings of the flows"""

    def __init__(self,q):

        self.master = Tk()
        self.label = Label(self.master, text="", width=10)
        self.label.pack()
        self.counting(q)

    # Countdown()
    def counting(self, q):
        try:
            self.i = q.get()
        except:
            self.label.after(1000, self.counting, q)

        if int(self.i) <= 0:
            print("Go")
            self.master.destroy()

        else:
            self.label.configure(text="%d" % self.i)
            print(i)
            self.label.after(1000, self.counting, q)

def printX(q):
    for i in range(10):
        print("test")
        q.put(9-i)
        time.sleep(1)
    return


if __name__ == '__main__':
    q = multiprocessing.Queue()

    n = multiprocessing.Process(name='Process2', target=printX, args = (q,)) 
    n.start() 

    GUI = Countdown(q)
    GUI.master.mainloop()

【问题讨论】:

  • 使用 after 不会让程序运行得更慢,它会让它运行得更快,因为你不会有处理队列的开销。由于您的counting 方法也使用after,所有多处理为您做的就是增加开销和复杂性。
  • 但我希望在调用 after 方法时数据可用。所以问题不在于 after 函数,而在于 after 函数调用的方法。每次完成计算需要 1 秒。因此,GUI 每秒无响应半秒。
  • GUI 将显示由正在与 RS232 通信的函数收集的数据。这需要时间。所以除了之后的 1 秒之外,由于值收集,它会增加一些时间。它使我的 GUI “冻结”每个循环。
  • 好的,如果您的实际问题是运行时间较长的代码,您需要在问题中提及。
  • 我已经编辑了原始问题。

标签: python-3.x tkinter python-multiprocessing


【解决方案1】:

多处理在交互式 Ipython 笔记本中不起作用。 Multiprocessing working in Python but not in iPython 作为替代方案,您可以使用 spyder。

【讨论】:

  • 请扩大您的回答范围并解释这有什么帮助。
  • 我更新了答案,但有很多选项,所以指定不是很有用
  • 解释可能的修复方法
  • 使用 spyder 或 python idle
【解决方案2】:

在您调用mainloop 之后,在窗口被销毁之前,不会运行任何代码。您需要在致电mainloop 之前开始您的其他流程。

【讨论】:

  • 我已更改订单但没有成功。关于我哪里出错的任何建议?
  • 我发现了问题。多处理在 ipython 笔记本中不起作用。感谢您的帮助。
【解决方案3】:

你调用了错误的 after 函数。第二个参数必须是要调用的函数的名称,而不是对该函数的调用。

如果你这样称呼它

self.label.after(1000, self.counting(q))

它将调用counting(q) 并等待返回值分配为要调用的函数。

用参数分配函数的语法是

self.label.after(1000, self.counting, q)

另外,在创建窗口之前启动第二个进程并调用counting

n = multiprocessing.Process(name='Process2', target=printX, args = (q,)) 
n.start() 

GUI = Countdown(q)
GUI.master.mainloop()

此外,您只需拨打mainloop 一次。任一个职位你都有,但你只需要一个


编辑:您还需要将(9-i) 放入队列中以使其倒计时。

q.put(9-i)

printX 函数内部

【讨论】:

  • 亲爱的 Noel,感谢您的更正。我忽略了第二个 mainloop 调用。我添加了更正并更新了代码(&和问题),但代码仍然没有运行。我一直在尝试混合,但没有成功。还有什么建议吗?
  • 我发现了问题。多处理在 ipython 笔记本中不起作用。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-14
  • 2017-06-29
  • 2020-05-19
  • 2012-01-17
  • 2011-12-17
相关资源
最近更新 更多