беспорядок в многопроцессорном подпроцессе

#python #multiprocessing #subprocess

#python #многопроцессорность #подпроцесс

Вопрос:

После выполнения некоторых вычислений линейным способом с помощью скрипта-модератора (см. ниже), вызывающего внутренний скрипт, выполняющий вычисления, я изо всех сил пытаюсь выполнить его при попытке с многопроцессорной обработкой. Кажется, что каждое ядро процессора проходит через этот набор списков (testRegister) и запускает вычисление, даже если другое ядро уже выполнило эту задачу ранее (в том же сеансе). Как я могу предотвратить это хаотичное поведение? Я впервые пытаюсь вызвать несколько процессоров с помощью Python.

Исправление: В первоначальном сообщении не было показано, что тест представляет собой строку, состоящую из вызова «внутреннего скрипта» с изменяющимися параметрами m1 и m2 рядом с фиксированными аргументами arg1 и arg2, принадлежащими исключительно этому «внутреннему скрипту».

 #!/usr/bin/env python3
import os
import subprocess as sub
import sys
import multiprocessing
fileRegister = []
testRegister = []


def fileCollector():
    for file in os.listdir("."):
        if file.endswith(".xyz"):
            fileRegister.append(file)
    fileRegister.sort()
    return fileRegister


def testSetup():
    data = fileRegister
    while len(data) > 1:
        for entry in fileRegister[1:]:
            m0 = str(fileRegister[0])
            m1 = str(entry)
            test =  str("python foo.py ")   str(m1)   str(" ")   str(m2)  
                    str(" --arg1 --arg2")  # formulate test condition
            testRegister.append(test)
            testRegister.sort()
        del data[0]
    return testRegister


def shortAnalysator():
    for entry in testRegister:
        print(str(entry))
        sub.call(entry, shell=True)
        del testRegister[0]


def polyAnalysator():
    # apparently each CPU core works as if the register were not shared
    # reference: https://docs.python.org/3.7/library/multiprocessing.html
    if __name__ == '__main__':
        jobs = []
        for i in range(3):   # safety marging to not consume all CPU
            p = multiprocessing.Process(target=shortAnalysator)
            jobs.append(p)
            p.start()


fileCollector()
testSetup()
shortAnalysator()       # proceeding expectably on one CPU (slow)
# polyAnalysator()        # causing irritation
sys.exit()```
  

Комментарии:

1. Что такое str(python foo.py --arg1 --arg2) ? Это не похоже на легальный Python.

2. @JohnAnderson Вы правы, и я соответствующим образом исправил вопрос.

Ответ №1:

Ваш polyAnalysator запускается shortAnalysator три раза. Попробуйте изменить свой polyAnalysator следующим образом и добавьте f метод. При этом используется multiprocessing Pool :

 from multiprocessing import Pool

def f(test):
    sub.call(test, shell=True)


def polyAnalysator():
    # apparently each CPU core works as if the register were not shared
    # reference: https://docs.python.org/3.7/library/multiprocessing.html
    with Pool(3) as p:
        p.map(f, testRegister)