Многопроцессорность Python + проблемы с подпроцессами - PullRequest
4 голосов
/ 28 марта 2012

У меня есть двоичный файл (скажем, a.out), который я хочу вызвать с разными конфигами.Я хочу запустить эти конфиги на 40-ядерном компьютере параллельно.Ниже приведен набросок моего кода.

Это очень просто: я генерирую конфигурацию и передаю ее рабочему, и рабочий вызывает двоичный файл с помощью конфигурации, используя подпроцесс.Я также перенаправляю вывод в файл.Давайте назовем этот кусок кода run.py

def worker(cmdlist, filename):
    outputfile = open(filename, 'wb')
    // here it essentially executes  a.out config > outputfile
    subprocess.call(cmdlist, stderr=outputfile, stdout=outputfile) 
    outputfile.close()

def main():
    pool = Pool(processes = 40)
    for config in all_configs
        filename, cmdlist = genCmd(config)
        res = pool.apply_async(worker, [cmdlist, filename])
        results.append(res)
    for res in results:
        res.get()
    pool.close()

Но после того, как я его запустил, я понял, что не запускаю столько процессов, сколько хочу.Я определенно представил более 40 работников, но в верхней части я вижу только около 20 человек.

Я вижу многие из run.py, которые находятся в «спящем» состоянии (то есть, «S» вверху).Когда я делаю ps auf, я также видел много run.py в состоянии «S +», без появления двоичного файла.Только около половины из них породили "a.out"

Мне интересно, почему это происходит?Я перенаправляю вывод на жесткий диск, смонтированный в сети, что может быть причиной, но сверху я вижу только 10% ва (что в моем понимании составляет 10% времени ожидания ввода-вывода).Я не думаю, что это приводит к 50% незанятых процессоров.Плюс, я должен по крайней мере вызвать двоичный файл, вместо того, чтобы застревать в run.py.Время выполнения моего двоичного файла также достаточно долго.Я действительно должен был видеть 40 рабочих мест, работающих долго.

Есть другие объяснения?Что-то я не так сделал в своем коде Python?

1 Ответ

1 голос
/ 29 марта 2012

Подход, который я использовал для одновременного использования множества одновременных процессов на нескольких ядрах, заключается в использовании p = subprocess.Popen (...) и p.Poll (). В вашем случае, я думаю, вы сможете вообще отказаться от использования пула. Я бы дал вам лучший пример, но, к сожалению, у меня больше нет доступа к этому коду.

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