2015-12-31 28 views
3

我正在用python编写我的第一个多处理程序。Python中的多处理来处理参数列表

我想创建一个要处理的值列表,并且8个进程(数字操作系统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 

而且,我有以下问题:

  • 该计划从来没有停止
  • 我走出RAM enter image description here
+0

丹尼尔桑切斯,我认为多处理是不同的线程,并且GIL没有与多处理锁定。 请参阅:http://stackoverflow.com/questions/3044580/multiprocessing-vs-threading-python?rq=1 –

+0

是的,我只是在发布我的愚蠢之后想过它,对不起:/ – Netwave

回答

1

简化您的代码到以下内容:

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 

使用你自己的代码,你似乎得到st科军在一段时间,但它是勇敢,在为不断增长的for循环数与尽可能多的数字:

167609 
180908 
185464 
187612 
209986 
236740 
209986 

而上....

+0

嗨,谢谢,但我认为你不能改变代码,因为你的代码使用超过8个进程,因为当你执行“p = Process(...“,您的将创建并启动一个新的进程,但不会替换原始列表os进程中的”p“,并且”if if not p.is_alive()“所有时间将返回”True“。 示例: lista = range (15) 打印LISTA 对于L在LISTA: 打印升 L = 0 打印LISTA –

+0

对不起,我不说英语非常好,但在我的代码只运行8个进程(在同一时间),并在你运行的代码是13(因为是“值”的大小)问题是你的代码是正确的,但是我需要每个进程尽可能快,然后我只运行8个进程,每个进程都有一个进程值,每当一个过程完成,我运行一个新的,直到每个值处理。感谢您的帮助:)真的你有最好的答案 –

+1

@RuiMarti ns,'processes = [process()for _in range(proc_number)]',并且循环遍历进程列表与您的代码中的索引逻辑完全相同,您可以使用枚举索引来处理[我] =进程'http://pastebin.com/ksQbvMET –

0

的问题是不是你的多码。它在战俘操作for循环:

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) 

它需要3 * POW(2 65)的4 GB内存倍。