Python、tkinter:在类实例中使用 multiprocessing.Pool(),在每秒运行一次的函数中从池中获取新数据

问题描述 投票:0回答:1

我仍在努力让线程池在类实例中工作。在一个文件中,我们将调用

test.py
我有以下内容:

import multiprocessing as mp

class Test:
    def __init__(self):
        pass

    def exec(self):
        pool = mp.Pool()
        result = pool.map(self.thread, range(0, 4))
        for r in result:
            print(r)

    def thread(self, i):
        return i * 2

init.py
然后我有:

import test

t = test.Test()
if __name__ == "__main__":
    t.exec()

这成功运行:当我从控制台运行

init.py
时,线程执行并返回双倍的数字。问题是我想让我的线程池成为一个类属性,而不是一个局部变量。因此
test.py
的正确内容应该是:

import multiprocessing as mp

class Test:
    def __init__(self):
        self.pool = mp.Pool()

    def exec(self):
        result = self.pool.map(self.thread, range(0, 4))
        for r in result:
            print(r)

    def thread(self, i):
        return i * 2

但这会返回以下错误:

NotImplementedError: pool objects cannot be passed between processes or pickled

我不想在进程之间传递池:调用池的

Test
的类实例应该仅保留在主线程上,因此它是在
if __name__ == "__main__"
检查下执行的。不过,我确实希望该池成为
self
的属性,以便可以重用,否则每次调用
exec
时我都必须创建一个新池。

exec
意味着每1秒重复调用一次,并每次使用线程池获取新数据。在完整代码中,我使用
tkinter
,因此在
self.root.after(1000, self.exec)
最初激活此函数之后使用
init.py
,然后该函数将重新安排自身并重复运行:
root.after
是我知道的没有主循环的唯一方法TK 阻止我的另一个循环运行。如果我们也考虑 tkinter,这里是
test.py
应该是什么样子的完整视图,请让我知道需要如何重写才能工作。

import multiprocessing as mp
import tkinter as tk

class Test:
    def __init__(self):
        self.pool = mp.Pool()
        self.root = tk.Tk()
        self.root.mainloop()

    def exec(self):
        result = self.pool.map(self.thread, range(0, 4))
        for r in result:
            print(r)
        self.root.after(1000, self.exec)

    def thread(self, i):
        return i * 2
python python-3.x multithreading tkinter multiprocessing
1个回答
0
投票

成功了。诀窍是使用两个类,主类将线程池发布给辅助类,然后辅助类使用它通过管道输入本地函数的结果。以下几行中的一些内容对我来说是可行的,重写为一种表示,因为我的最终结果已经有点分歧了......如果您认为它可以进一步改进,请告诉我。

import multiprocessing as mp

class Test1:
    def __init__(self):
        pass

    def exec(self, pool):
        return pool.map(self.thread, range(0, 4))

    def thread(self, i):
        return i * 2

class Test2:
    def __init__(self):
        self.pool = mp.Pool()
        self.other = Test1()

    def obtain(self):
        return self.other.exec(self.pool)

t = Test2()
t.obtain()
© www.soinside.com 2019 - 2024. All rights reserved.