我仍在努力让线程池在类实例中工作。在一个文件中,我们将调用
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
成功了。诀窍是使用两个类,主类将线程池发布给辅助类,然后辅助类使用它通过管道输入本地函数的结果。以下几行中的一些内容对我来说是可行的,重写为一种表示,因为我的最终结果已经有点分歧了......如果您认为它可以进一步改进,请告诉我。
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()