Я новичок в написании параллельного кода.
Я пишу код, который берет идентификатор пользователя и пытается вернуть полное имя пользователя, запрос занимает секунду или около того, поэтому я надеялся задействовать многопроцессорность для более быстрого сбора данных; Я думаю, что близок, но я не понимаю, как правильно реализовать фреймворк.
from subprocess import getoutput
from multiprocessing import Pool
all_users = ['User1', 'User2', 'User3', 'User4', 'User5', 'User6'] # example list
def get_name(userid):
name = getoutput('net users {} /domain | findstr "full name:"'.format(userid)).replace('Full Name', '').strip().split('\n')[0]
return {userid : name}
if __name__ == '__main__':
with Pool(4) as p:
print(p.map(get_name, all_users))
print(' --------- finished')
print(' - exiting - '))
Это всего лишь один шаг в многоэтапном сценарии; и вывод выглядит следующим образом: (игнорируйте часть «имя пользователя не может быть найдено», просто пример)
- exiting -
- exiting -
- exiting -
- exiting -
[{'User1': 'The user name could not be found.'}, {'User2': 'The user name could not be found.'}, {'User3': 'The user name could not be found.'}, {'User4': 'The user name could not be found.'}, {'User5': 'The user name could not be found.'}, {'User6': 'The user name could not be found.'}]
--------- finished
- exiting -
Я пытаюсь структурировать программу следующим образом:
Я пробовал читать на эту тему из разных источников, но я просто не могу как-то понять структуру ... как я понял, я получаю четыре - выходящих - утверждения в начале, поскольку у меня 4 ядра, но как сделать Я инкапсулирую эту часть кода так, чтобы пока она работала, больше ничего не происходило и - exiting - записывалось только один раз в конце.






Вам нужно использовать оператор pool.close () в вашем цикле with:
with Pool(4) as p:
print(p.map(get_name, all_users))
p.close()
Разве оператор with не должен автоматически обрабатывать закрытие объекта Pool?
Джош Хейс уже дал правильный ответ. Если вы используете такой пул, он будет вызывать terminate при выходе (https://docs.python.org/3.4/library/multiprocessing.html?highlight=process), начиная с Python 3.3. Вы должны добавить p.close(), чтобы правильно закончить. Однако ваша последняя скобка слишком велика, и вы не должны видеть более одной печати finished и exiting, потому что эти вызовы не входят в пул. Как начать свой сценарий? Какую версию Python вы используете?
Редактировать: Вы можете попробовать добавить:
import os
def info(title):
print(title)
print('module name:', __name__)
print('parent process:', os.getppid())
print('process id:', os.getpid())
all_users = ['User1', 'User2', 'User3', 'User4', 'User5', 'User6'] # example list
def get_name(userid):
name = getoutput('net users {} /domain | findstr "full name:"'.format(userid)).replace('Full Name', '').strip().split('\n')[0]
print(info("p "))
return {userid : name}
и вызовите info("whatever") вместо exiting и посмотрите, какие процессы здесь работают.
Какую ОС вы используете? По крайней мере, в Linux это имеет смысл.
Я использую Python 3.6.3 x64; Это действительно весь сценарий, который я вставил, и результат выглядит странным ... 4 оператора выхода в начале, затем сценарий запускается, а затем все остальное происходит по порядку; P.S. Оператор with не обрабатывает автоматическое закрытие объектов Pool?
Я немного смущен. Я тестировал его с помощью Python 3.5.2, и мои процессы не завершаются, а основной процесс ожидает завершения всех. Однако в документации указано, что terminate() Stops the worker processes immediately without completing outstanding work. When the pool object is garbage collected terminate() will be called immediately. Новое в версии 3.3: Объекты пула теперь поддерживают протокол управления контекстом - см. Типы диспетчера контекста. __enter __ () возвращает объект пула, а __exit __ () вызывает terminate ().
Ответ на аналогичный вопрос был дан по следующей ссылке: множественный вывод, возвращаемый функцией многопроцессорной обработки Python
Обобщить:
# Import stuff
#If the worker code is in the main thread, exclude it from the if statement:
def worker():
#worker code
if __name__ == '__main__':
#execute whatever you want, it will only be executed
#as often as you intend it to
#execute the function that starts multiprocessing,
#All code outside of the if statement will be executed multiple times
#depending on the # of assigned worker threads.
Нашел интересное объяснение; stackoverflow.com/a/14626474/9039988