Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么python模式可以用于并行化?_Python_Multithreading_Python 2.7_Parallel Processing_Joblib - Fatal编程技术网

什么python模式可以用于并行化?

什么python模式可以用于并行化?,python,multithreading,python-2.7,parallel-processing,joblib,Python,Multithreading,Python 2.7,Parallel Processing,Joblib,cmd是一个处理参数x并将输出打印到stdout的函数。例如,它可能是 def cmd(x): print(x) 调用cmd()的串行程序如下所示 for x in array: cmd(x) 为了加速程序,我希望它并行运行。标准输出可能出现故障,但一个x的输出不能被另一个x的输出破坏 在python中可以有多种方法来实现这一点。我想是这样的 from joblib import Parallel, delayed Parallel(n_jobs=100)(delayed(cmd)(

cmd
是一个处理参数x并将输出打印到stdout的函数。例如,它可能是

def cmd(x):
  print(x)
调用
cmd()
的串行程序如下所示

for x in array:
  cmd(x)
为了加速程序,我希望它并行运行。标准输出可能出现故障,但一个x的输出不能被另一个x的输出破坏

在python中可以有多种方法来实现这一点。我想是这样的

from joblib import Parallel, delayed
Parallel(n_jobs=100)(delayed(cmd)(i) for i in range(100))
就代码的简单性/可读性和效率而言,这是在python中实现这一点的最佳方法吗

此外,上述代码在python3上运行正常。但不是在python2上,我得到了以下错误。这是一个可能导致错误的问题吗

/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site packages/joblb/externals/loky/backend/semlock.py:217:RuntimeWarning:OSX上的信号量已损坏,发布版本可能会增加其最大值 “增加其最大值”,RuntimeWarning)


谢谢。

如果您使用的是python3,那么您可以使用标准库

考虑以下用法:

with concurrent.futures.ProcessPoolExecutor(100) as executor:
     for x in array:
         executor.submit(cmd, x)
在标准库中


使用lock可以保证
lock.acquire()
lock.release()
之间的代码一次只能由一个线程执行<代码>打印方法在python3中已经是线程安全的,因此即使没有锁,输出也不会中断。但是,如果线程(它们修改的对象)之间共享任何状态,则需要一个锁。

我将使用以下代码来解决问题(假设我们讨论的是CPU限制的操作):

输出:

['result for 0', 'result for 1', 'result for 2', 'result for 3', 'result for 4', 'result for 5', 'result for 6', 'result for 7', 'result for 8', 'result for 9']
result for 0
result for 1
result for 2
result for 3
result for 4
result for 5
result for 7
result for 6
result for 8
result for 9
编辑-另一个在计算后立即获得结果的实现-
处理
队列
,而不是
映射

import multiprocessing
import random


def cmd(value, result_queue):
    # some CPU heavy calculation
    for dummy in range(10 ** 8):
        random.random()
    # result
    result_queue.put("result for {}".format(value))


if __name__ == '__main__':

    data = [val for val in range(10)]
    results = multiprocessing.Queue()

    LIMIT = 3  # 3 - is the number of processes (the number of CPU cores used)
    counter = 0
    for val in data:
        counter += 1
        multiprocessing.Process(
            target=cmd,
            kwargs={'value': val, 'result_queue': results}
            ).start()
        if counter >= LIMIT:
            print(results.get())
            counter -= 1
    for dummy in range(LIMIT - 1):
        print(results.get())
输出:

['result for 0', 'result for 1', 'result for 2', 'result for 3', 'result for 4', 'result for 5', 'result for 6', 'result for 7', 'result for 8', 'result for 9']
result for 0
result for 1
result for 2
result for 3
result for 4
result for 5
result for 7
result for 6
result for 8
result for 9

只是想确定一下。这能保证打印结果不会相互交错吗?如果您使用的是python3,那么可以。但更好的解决方案可能是使用模块。结果是否可以立即获得?当我在生产中使用代码时,我不确定为什么结果不会立即打印出来。我不确定这是由于io缓冲区问题还是与ProcessPoolExecutor相关的原因。刷新io自助餐是否会导致问题?除了调用
print
,您的
cmd
方法是否还执行了其他操作?是。有一些代码要进行计算,然后打印结果。如何确保并发运行的代码不超过n
cmd()
?像我这样的简单方法是没有办法的。并行处理是一个复杂的课题。对于更高级的线程解决方案,请从这里开始:我希望在结果可用时立即打印(无序即可)。
pool.map()。选中“编辑添加到答案”以获得另一版本的代码。我修复了原始消息中的错误。