我希望有人能够为我提供有关多处理的一些问题,以及我是否对尝试使用的正确方法有所帮助。
下面是一些我已经写过的示例代码,我认为它们表明了我要完成的工作:
import multiprocessing
import time
# Example Class that does some math things
class DoMath(object):
def __init__(self, total):
self.total = total
def add(self, a, b):
print("Addition: ", int(a+b))
return int(a+b)
def sub(self, a, b):
print("Subtraction: ", int(a - b))
return int(a-b)
def totals(self, add, minus):
self.total += (add + minus)
print("Current Total: ", self.total)
return int(self.total)
# Pool worker doing simple tasks, sleep is there so it doesn't complete instantly
def worker(a, b):
time.sleep(1)
add = values.add(a, b)
sub = values.sub(a, b)
values.totals(add, sub)
return values
# Call back function
def callback(x):
print('worker done')
print(x.total)
return x
if __name__ == '__main__':
math_numbers = {"1": {"a": 1, "b": 1}, "2": {"a": 2, "b": 2}}
values = DoMath(0)
pool_size = 1
pool = multiprocessing.Pool(
processes=pool_size
)
for key, params_dict in math_numbers.items():
test = pool.apply_async(worker, args=tuple(), kwds=params_dict, callback=callback)
pool.close()
pool.join()
print(test)
print(values.total)
运行此命令时,这些是我得到的结果:
Addition: 2
Subtraction: 0
Current Total: 2
worker done
2
Addition: 4
Subtraction: 0
Current Total: 6
worker done
6
<multiprocessing.pool.ApplyResult object at 0x104c5a0b8>
0
我的第一个问题与我如何在第43行实例化DoMath
类有关。像这样启动类似乎可行,但是我的问题是我的实际代码中的所有内容都不在单个文件中,而且我还没有还无法弄清楚如何将类传递给apply_async
函数。尝试将其放入json字典似乎对我不起作用。我的实际代码是建立连接池,以便我可以向API发出REST请求,目前,我能够使其正常工作的唯一方法是为每个工作人员创建一个新连接。这似乎效率极低,是否有更好的方法来解决?这是我所拥有的vs我想做的一个例子:
当前:
def worker(arg1, arg2, arg3):
connection = connect(
url=arg1,
port=arg2
)
connection.api(do_something=arg3)
我想做什么:
def worker(arg3, connection):
connection.api(do_something=arg3)
第二,这可能是一个基本的误解,但是有没有办法在池完全结束之前处理这些工作程序的结果?使用我的实际代码,我正在运行超过15000名工人,每个工人将返回大约1万个项目的列表。我想将这些写入文件,但不是要创建15,000多个文件,而是希望该过程将它们追加到文件中,每10万行滚动到一个新文件。我意识到我可以强迫每个工作人员将其输出仅写入工作人员内部或回调中的文件,但是我担心如果尝试通过多个工作人员同时写入同一文件来进行翻转过程,数据可能丢失或未正确提交。
在我共享的第一个代码块的第56和57行上,我对这些结果有些困惑。我不太确定如何使用ApplyResult
对象或应该包含的对象。更进一步,我真的不明白为什么当池和回调都返回实际值6时,工作程序外部的values.total
对象为何返回0。这是怎么回事?