Python 中的多重处理以处理参数列表

Multiprocessing in Python to process a list of parameters

我正在 python 中编写我的第一个多处理程序。

我想创建一个要处理的值列表,8 个进程(os CPU 个内核)将使用并处理该值列表。

我写了下面的python代码:

__author__ = 'Rui Martins'

from multiprocessing import cpu_count, Process, Lock, Value

def proc(lock, number_of_active_processes, valor):
    lock.acquire()
    number_of_active_processes.value+=1
    print "Active processes:", number_of_active_processes.value
    lock.release()
    # DO SOMETHING ...
    for i in range(1, 100):
        valor=valor**2
    # (...)
    lock.acquire()
    number_of_active_processes.value-=1
    lock.release()

if __name__ == '__main__':
    proc_number=cpu_count()
    number_of_active_processes=Value('i', 0)
    lock = Lock()
    values=[11, 24, 13, 40, 15, 26, 27, 8, 19, 10, 11, 12, 13]
    values_processed=0

    processes=[]
    for i in range(proc_number):
        processes+=[Process()]
    while values_processed<len(values):
        while number_of_active_processes.value < proc_number and values_processed<len(values):
            for i in range(proc_number):
                if not processes[i].is_alive() and values_processed<len(values):
                    processes[i] = Process(target=proc, args=(lock, number_of_active_processes, values[values_processed]))
                    values_processed+=1
                    processes[i].start()

            while number_of_active_processes.value == proc_number:
                # BUG: always number_of_active_processes.value == 8 :(
                print "Active processes:", number_of_active_processes.value

    print ""
    print "Active processes at END:", number_of_active_processes.value

而且,我有以下问题:

将您的代码简化为以下内容:

def proc(lock, number_of_active_processes, valor):
    lock.acquire()
    number_of_active_processes.value += 1
    print("Active processes:", number_of_active_processes.value)
    lock.release()
    # DO SOMETHING ...
    for i in range(1, 100):
        print(valor)
        valor = valor **2
    # (...)
    lock.acquire()
    number_of_active_processes.value -= 1
    lock.release()


if __name__ == '__main__':
    proc_number = cpu_count()
    number_of_active_processes = Value('i', 0)

    lock = Lock()
    values = [11, 24, 13, 40, 15, 26, 27, 8, 19, 10, 11, 12, 13]
    values_processed = 0

    processes = [Process() for _ in range(proc_number)]
    while values_processed < len(values)-1:
        for p in processes:
            if not p.is_alive():
                p = Process(target=proc,
                            args=(lock, number_of_active_processes, values[values_processed]))
                values_processed += 1
                p.start()

如果你 运行 它像上面 print(valor) 添加的那样,你会确切地看到发生了什么,你的勇气呈指数级增长到你 运行 内存不足的程度,你不会当你陷入 for 循环时,不要陷入困境。

这是第 12 个进程的输出,在几分之一秒后添加了一个 print(len(srt(valor))),它一直在继续:

2
3
6
11
21
.........
59185
70726
68249
73004
77077
83805
93806
92732
90454
104993
118370
136498
131073

只需将循环更改为以下内容:

for i in range(1, 100):
    print(valor)
    valor = valor *2

最后创建的号码是:

 6021340351084089657109340225536

使用您自己的代码,您似乎陷入了困境,但它在 for 循环中不断增长,数字的位数与以下数字一样多:

167609
180908
185464
187612
209986
236740
209986

然后……

问题不在于您的多处理代码。它是 for 循环中的 pow 运算符:

for i in range(1, 100):
        valor=valor**2

最后的结果是pow(val, 2**100),这个太大了,计算起来太费时间和内存了。所以你最后遇到了内存不足的错误。

4 GB = 4 * pow(2, 10) * pow(2, 10) * pow(2, 20) * 8 bit = 2**35 bit

对于最小的数字 8:

pow(8, 2**100) = pow(2**3, 2**100) = pow(2, 3*pow(2, 100))
pow(2, 3*pow(2, 100))bit/4GB = 3*pow(2, 100-35) = 3*pow(2, 65)

需要4GB内存的3*pow(2, 65)倍