2 Многопроцессорный модуль

 from __future__ import print_function
import multiprocessing


def countdown(count):
    while count > 0:
        print("Count value", count)
        count -= 1
    return

if __name__ == "__main__":
    p1 = multiprocessing.Process(target=countdown, args=(10,))
    p1.start()

    p2 = multiprocessing.Process(target=countdown, args=(20,))
    p2.start()

    p1.join()
    p2.join()

 

Здесь каждая функция выполняется в новом процессе. Так как новый экземпляр Python VM работает код, нет GIL и вы получите параллелизм работает на нескольких ядрах.

Process.start метод запускает этот новый процесс и запустить функцию передается в target аргументе с аргументами args . Process.join метод ожидает конца выполнения процессов p1 и p2 .

Новые процессы запускаются по- разному в зависимости от версии питона и на котором цех изготовления печатных форм код работает , например:

  • Windows , использует spawn , чтобы создать новый процесс.
  • В системах UNIX и версии ранее чем 3.3, процессы создаются с помощью fork .
    Обратите внимание, что этот метод не учитывает использование fork в POSIX и, таким образом, приводит к неожиданному поведению, особенно при взаимодействии с другими многопроцессорными библиотеками.
  • С помощью системы UNIX и версии 3.4+, вы можете выбрать , чтобы начать новые процессы либо с fork , forkserver или spawn , используя multiprocessing.set_start_method в начале программы. forkserver и spawn метода медленнее , чем разветвление , но избежать некоторого неожиданного поведения.

POSIX вилка использование:

После разветвления в многопоточной программе дочерний процесс может безопасно вызывать только асинхронно-безопасные функции до тех пор, пока он не вызовет execve.
( См )

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

  • Если вы используете Lock в MainThread и передать его в другой поток , который предполагают , чтобы зафиксировать ее в какой - то момент. Если fork встречается , одновременно, новый процесс начнется с заблокированным замком , который никогда не будет выпущен как второй поток не существует в этом новом процессе.

На самом деле, такого рода поведение не должно происходило в чистом питоне , как multiprocessing обрабатывает это правильно , но если вы взаимодействуете с другой библиотеке, такое поведение может встречается , , что привело к краху вашей системы (например , с NumPy / ускорен на MacOS).