Я хотел создать модуль python с удобной функцией для параллельного запуска команд с использованием Python 3.7 в Windows.(для команд az cli)
Я хотел создать функцию, которая бы:
- была простой в использовании: просто передайте список команд в виде строк, и они будут выполняться параллельно.
- Позвольте мне посмотреть вывод, сгенерированный командами.
- Используемая сборка в библиотеках python
- Работает одинаково хорошо в Windows и Linux (многопроцессорная обработка Python использует fork (), иВ Windows нет функции fork (), поэтому иногда многопроцессорный код будет работать в Linux, но не в Windows.)
- Может быть преобразован в импортируемый модуль для большего удобства.
Это было удивительно сложно, я думаю, возможно, раньше это было невозможно в старых версиях python?(Я видел несколько вопросов по 2-8 лет, в которых говорилось, что вы должны использовать if __name__==__main__:
для запуска параллельной обработки, но я обнаружил, что это не сработало предсказуемо, когда дело дошло до создания импортируемого модуля.
def removeExtraLinesFromString(inputstring):
stringtoreturn = ""
for line in inputstring.split("\n"):
if len(line.strip()) > 0: #Only add non empty lines to the stringtoreturn
stringtoreturn = stringtoreturn + line
return stringtoreturn
def runCmd(cmd): #string of a command passed in here
from subprocess import run, PIPE
stringtoreturn = str( run(cmd, shell=True, stdout=PIPE).stdout.decode('utf-8') )
stringtoreturn = removeExtraLinesFromString(stringtoreturn)
return stringtoreturn
def exampleOfParrallelCommands():
if __name__ == '__main__': #I don't like this method, because it doesn't work when imported, refractoring attempts lead to infinite loops and unexpected behavior.
from multiprocessing import Pool
cmd = "python -c \"import time;time.sleep(5);print('5 seconds have passed')\""
cmds = []
for i in range(12): #If this were running in series it'd take at least a minute to sleep 5 seconds 12 times
cmds.append(cmd)
with Pool(processes=len(cmds)) as pool:
results = pool.map(runCmd, cmds) #results is a list of cmd output
print(results[0])
print(results[1])
return results
Когда я попытался импортировать это как модуль, он не работал (делает так из-за оператора if), поэтому я попытался переписать код, чтобы переместить оператор if, я думаю, что однажды удалил его, что вызваломой компьютер должен зацикливаться до тех пор, пока я не закрою программу. В другой раз я смог импортировать модуль в другую программу на python, но чтобы это работало, мне пришлось добавить __name__ == '__main__'
, и это очень интуитивно понятно.
Я почти сдался, но после 2 дней поиска по тоннам веб-сайтов и публикаций на Python я наконец-то понял, как это сделать, увидев код пользователя jfs в этом вопросе-ответе ( Python: параллельный запуск подпроцесса cat * )Я изменил его код, чтобы он лучше подходил к ответу на мой вопрос.