Есть ли способ назначить разные задания (процессы) для конкретного ядра в Linux с помощью Python? - PullRequest
1 голос
/ 15 октября 2019

У меня есть функции Python, которые должны работать параллельно в среде Linux с использованием нескольких ядер. Есть ли способ указать, какое ядро ​​должно использоваться для каждого процесса явно?

В настоящее время я использую многопроцессорный модуль python для запуска этих функций python как параллельных процессов в 4 ядрах.

import multiprocessing as mp

def hello(name, msg):
    try:
        print("Hello {}".format(name))
        print(msg)
        return true
    except Exception:
        return False

pool = mp.Pool(mp.cpu_count())

msg = "It's a holiday!"
name_list = ["A", "B", "C"]

hello_status = pool.starmap(hello,[(name, msg) for name in name_list])

print(hello_status)

1 Ответ

1 голос
/ 15 октября 2019

Возможно с комбинацией os.sched_setaffinity и os.sched_getaffinity. Строка документа говорит:

Подпись: os.sched_setaffinity (pid, mask, /)

Строка документа:

Установите привязку ЦП процесса, идентифицированного pid, кмаска.

маска должна представлять собой итерацию целых чисел, идентифицирующих ЦП.

Тип: builtin_function_or_method

Я не смог найти специфическую для Python документацию, но этиСправочные страницы должны быть хорошим первым источником информации.

ОБНОВЛЕНИЕ:

Я решил заглянуть в модуль multiprocessing и подготовить рабочий пример. Я придумал два способа сделать это, используя multiprocessing.Pool класс. Первый метод - передача аргумента initializer вызову конструктора Pool. Второй - с помощью функции Pool.map.

import os
from itertools import cycle
import multiprocessing as mp

def _myinit():
    my_pid = os.getpid()
    old_aff = os.sched_getaffinity(0)
    os.sched_setaffinity(0, [0, 3])
    new_aff = os.sched_getaffinity(0)
    print("My pid is {} and my old aff was {}, my new aff is {}".format(my_pid, old_aff, new_aff))

def map_hack(AFF):
    my_pid = os.getpid()
    old_aff = os.sched_getaffinity(0)
    os.sched_setaffinity(0, AFF)
    return (my_pid, old_aff, os.sched_getaffinity(0))

PROCESSES = os.cpu_count()

# just an example iterable you could use for the map_hack
# elements of cpus must be iterables, because of os.sched_setaffinity
_mycpus = cycle(os.sched_getaffinity(0))
cpus = [[next(_mycpus)] for x in range(PROCESSES)]

# Since Python 3.3 context managers are supported for mp.Pool

# using initializer argument to change affinity
with mp.Pool(processes=PROCESSES, initializer=_myinit) as pool:

    # do something conditional on your affinity 

    pool.close()
    pool.join()
    print("")

# using mp.Pool.map hack to change affinity
with mp.Pool(processes=PROCESSES) as pool:
    for x in pool.map(map_hack, cpus, chunksize=1):
        print("My pid is {} and my old aff was {}, my new aff is {}".format(*x))

    # do something conditional on your affinity 

    pool.close()
    pool.join()

Обратите внимание, что с помощью initializer я жестко закодировал сходство всех процессов для первого и четвертого процессоров (0, 3), но это только потому, что ябыло немного хитрее использовать cycle, как я делал с map_hack. Я также хотел продемонстрировать, что вы можете установить сродство для любого (легального) числа процессоров.

Я предлагаю вам ознакомиться с кодом и убедиться, что вы понимаете его, прочитав соответствующие документы и поигравшись с ним, изменив некоторые параметры. Само собой разумеется, что все утверждения print предназначены только для того, чтобы мы убедили себя в том, что методы работают.

Наконец, если вам нужен больше контроля, я бы предложил вам использовать mp.Process объекты вместо mp.Pool. Там же могут пригодиться те же инструменты из os.

WINDOWS:

Это не будет работать, если вы используете Windows. Из документов :

Эти функции управляют тем, как процесс выделяет время ЦП операционной системой. Они доступны только на некоторых платформах Unix. За более подробной информацией обращайтесь к руководствам Unix.

В этом случае вы можете посмотреть win32process, в частности win32process.SetProcessAffinityMask и win32process.GetProcessAffinityMask, см. здесь .

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