Многопроцессорная обработка в Python2 .7 - PullRequest
1 голос
/ 18 марта 2020

Я пытаюсь понять «многопроцессорный» модуль с помощью примеров прежде, чем я начну применять его в своем основном коде, и я немного запутался в последовательности выполнения в этом коде.

Код:

import multiprocessing as mp
import time
import os

def square( nums , r , t1 ) :
    print ("square started at :")
    print ("%.6f" % (time.clock()-t1))
    for n in nums :
        r.append(n*n)
    print ("square endeded at :")
    print ("%.6f" % (time.clock()-t1))

def cube ( nums , r , t1 ) :
    #time.sleep(2)
    print ("cube started at   :")
    print ("%.6f" % (time.clock()-t1))
    for n in nums :
        r.append(n*n*n)
    print ("cube endeded at   :")
    print ("%.6f" % (time.clock()-t1))


if __name__ == "__main__" :
    numbers = range(1,1000000)
    results1 = []
    results2 = []
    t1 = time.clock()

    # With multiprocessing :
    p1 = mp.Process(target = square , args = (numbers , results1 , t1))
    p2 = mp.Process(target = cube   , args = (numbers , results2 , t1))
    p1.start()
    #time.sleep(2)
    p2.start()
    p1.join()
    print ("After p1.join()   :")
    print ("%.6f" % (time.clock()-t1))
    p2.join()

    '''
    # Without multiprocessing :
    square(numbers , results1 ,t1)
    cube(numbers , results2 , t1)

    '''
    print ("square + cube :")
    print ("%.6f" % (time.clock()-t1))

Вывод кода:

square started at :  
0.000000  
square endeded at :  
0.637105  
After p1.join()   :  
12.310289  
cube started at   :  
0.000000  
cube endeded at   :  
0.730428  
square + cube :  
13.057885

И у меня есть несколько вопросов:

  1. согласно приведенному выше коду и времени должно быть в этом порядке?

square started at :<br> cube started at :<br> square endeded at :<br> cube endeded at :<br> After p1.join() :<br> square + cube :

почему до достижения программы (p1.join ()) требуется так много времени (p1.join ()), несмотря на то, что она завершила "квадрат" несколькими секундами раньше?
другими словами, почему квадрат и куб занимают около 13 секунд, чтобы запустить в режиме реального времени 0,7 с!

в моем основном коде. Я хотел бы запустить вторую функцию (в данном примере куб) после одной секунды задержки от первой функции, поэтому я попытался поместить задержку (time.sleep (1)) между «p1.start ()» и «p2.start ()», но это не сработало, и обе функции все еще начинаются с (0.000000s), затем я поместил задержка в начале функции «куб», и она также не работала, поэтому мой вопрос, как добиться задержки между этими двумя функциями?

1 Ответ

0 голосов
/ 20 марта 2020

При работе с многопоточностью все виды других факторов могут влиять на то, что вы видите. Поскольку вы буквально добавляете подпроцессы в диспетчер процессов вашей ОС, они будут работать совершенно отдельно от вашей запущенной программы, включая наличие собственных ресурсов, приоритетов планирования, каналов и т. Д. c.

1.) Нет Причина в том, что каждый дочерний процесс получает свой собственный выходной буфер, в который он записывает, который записывается обратно в родительский процесс. Поскольку вы запускаете оба дочерних процесса, а затем указываете родительскому процессу блокировать поток до завершения подпроцесса p1, дочерний процесс p2 не может записать свой буфер в родительский процесс до завершения процесса p1. Вот почему, несмотря на ожидание 12 секунд, результат процесса p2 по-прежнему составляет 0,7 секунды.

2.) Трудно точно знать, почему подпроцессу потребовалось 12 секунд, чтобы запустить его. Это может быть что-то в вашем коде или это может быть дюжина других причин, таких как совершенно другой процесс, который на время угоняет ваш процессор. Во-первых, time.clock, вероятно, не то, что вы ищете, если вы пытаетесь измерить фактическое время по сравнению с тем, сколько времени процесс потратил на процессор. Другие комментаторы правильно рекомендовали использовать высокопроизводительный счетчик для точного отслеживания времени, чтобы убедиться, что в измерении времени нет никаких странностей. Кроме того, при запуске, запуске и завершении нового процесса всегда есть некоторый уровень издержек, хотя, конечно, он не стоит 12 секунд. Лучший способ определить, являются ли эти 12 секунд чем-то, что вы могли бы контролировать или нет, - это запустить приложение несколько раз и посмотреть, есть ли большая разница между суммарным результатом. Если есть, это могут быть другие условия, связанные с компьютером, на котором он запущен.

3.) Я предполагаю, что проблема заключается в измерении time.clock. Вызов time.clock вычисляет, сколько времени процесс потратил на процессор. Поскольку вы используете несколько процессов, time.clock сбрасывается в 0 при запуске процесса. Это относительное время, а не абсолютное время, и относительно продолжительности процесса. Если вы перемещаетесь между процессами или спящими потоками, time.clock не обязательно будет увеличивать то, что вы думаете, измеряя абсолютное время. Вы должны использовать что-то вроде time.time () или, еще лучше, высокопроизводительный счетчик для правильного отслеживания реального времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...