Python使用多处理
我想在python 3.6中使用多处理。 我有一个用不同参数运行一个method
的for loop
。 目前,它每次都在运行一个,这需要花费很长时间,所以我正在尝试使用多处理。 这是我的:
def test(self):
for key, value in dict.items():
pool = Pool(processes=(cpu_count() - 1))
pool.apply_async(self.thread_process, args=(key,value))
pool.close()
pool.join()
def thread_process(self, key, value):
# self.__init__()
print("For", key)
我认为我的代码使用3个进程来运行一个method
但我想每个进程运行1个方法,但我不知道这是如何完成的。 我正在使用4核btw。
您在for循环的每次迭代中都创建一个池。 事先建立一个池,应用你想在多处理中运行的进程,然后加入它们:
from multiprocessing import Pool, cpu_count
import time
def t():
# Make a dummy dictionary
d = {k: k**2 for k in range(10)}
pool = Pool(processes=(cpu_count() - 1))
for key, value in d.items():
pool.apply_async(thread_process, args=(key, value))
pool.close()
pool.join()
def thread_process(key, value):
time.sleep(0.1) # Simulate a process taking some time to complete
print("For", key, value)
if __name__ == '__main__':
t()
你没有填充你的multiprocessing.Pool
与数据池 - 你重新初始化每个循环的池。 在你的情况下,你可以使用Pool.map()
为你做所有繁重的工作:
def thread_process(args):
print(args)
def test():
pool = Pool(processes=(cpu_count() - 1))
pool.map(thread_process, your_dict.items())
pool.close()
if __name__ == "__main__": # important guard for cross-platform use
test()
另外,考虑到所有这些我self
观点,我认为你是从类实例中抢走了它,如果是的话 - 不要,除非你知道你在做什么。 由于Python中的多处理基本上同多处理一样工作(不像多线程),所以你不能共享你的内存,这意味着你的数据在进程之间交换时被腌渍,这意味着任何不能被腌制的东西(比如实例方法)不会被调用。 你可以在这个答案上阅读更多关于这个问题。
我认为我的代码使用3个进程来运行一个方法,但我想每个进程运行1个方法,但我不知道这是如何完成的。 我正在使用4核btw。
不,你实际上在这里使用了正确的语法来利用3个内核在每个内核上独立运行一个任意函数。 你不能神奇地利用3个核心在一个任务上一起工作,没有明确地将其作为算法本身的一部分/编码你的自己经常使用线程(在python中它们与在语言之外不同)。
然而,您每次循环都要重新初始化池,您需要做这样的事情,而不是实际执行此操作:
cpus_to_run_on = cpu_count() - 1
pool = Pool(processes=(cpus_to_run_on)
# don't call a dictionary a dict, you will not be able to use dict() any
# more after that point, that's like calling a variable len or abs, you
# can't use those functions now
pool.map(your_function, your_function_args)
pool.close()
如果您想更好地了解它的工作原理,请参阅python multiprocessing
文档以获取更具体的信息。 在python下,你不能利用线程来使用默认的CPython解释器进行多处理。 这是因为所谓的全局解释器锁定,它会停止从python内部进行并发资源访问。 GIL在其他语言实现中不存在,并且不像C和C ++这样的其他语言必须处理(因此,与CPython不同,实际上可以并行使用线程来协同工作)
Python通过在使用多处理模块时简单地创建多个解释器实例来解决这个问题,并且通过在进程之间复制数据来完成实例之间传递的任何消息(即,两个解释器实例通常不会触及相同的内存)。 然而,这并不会发生在误导性的线程模块中,因为这个过程称为上下文切换,通常实际上会减慢进程的速度。 今天的线程使用有限,但是提供了一个更简单的方法来处理非GIL锁定进程,比如套接字和文件读/写,而不是异步python。
除此之外,尽管多处理存在更大的问题。 你写给标准输出。 你不会得到你想要的收益。 想想看。 每个进程都“打印”数据,但其全部显示在一个终端/输出屏幕上。 因此,即使您的流程是“打印”,但它们并不是独立实现的,并且信息必须合并回到文本界面所在的另一个流程(即您的控制台)。 因此,这些进程将任何它们将要写入的某种缓冲区写入,然后必须将其复制(正如我们从多处理的工作过程中所学到的)到另一个将接收缓冲数据并输出它的进程。
通常,虚拟程序使用打印作为显示这些过程执行之间没有顺序的方式,它们可以在不同的时间完成,它们并不意味着展示多核处理的性能优势。
链接地址: http://www.djcxy.com/p/79395.html