Multiprocessing.Process.start: примеры (PYTHON)

Метод start объекта Process в модуле multiprocessing
Раздел: Многопроцессорность, Процессы
multiprocessing.Process.start: None

Описание функции multiprocessing.Process.start

Метод start() объекта multiprocessing.Process предназначен для запуска отдельного процесса. Вызов этого метода инициирует выполнение целевой функции, указанной в параметре target, в новом процессе операционной системы. Это основной способ создания параллельных вычислений, позволяющий обойти ограничения Global Interpreter Lock (GIL) в Python.

Использование метода становится необходимым, когда требуется выполнить тяжелые вычислительные задачи, не зависящие от состояния глобальной памяти интерпретатора. Также метод применим для задач ввода-вывода, которые могут выполняться асинхронно.

Аргументы для создания процесса задаются при инициализации объекта Process и включают:

  • target – вызываемый объект (функция или метод), который будет запущен в новом процессе. Если значение не указано, используется метод run() класса Process.
  • name – строка, задающая имя процесса. Полезно для идентификации процессов при отладке.
  • args – кортеж аргументов, которые будут переданы целевой функции.
  • kwargs – словарь именованных аргументов для передачи в целевую функцию.
  • daemon – логический флаг. Если установлен в True, процесс становится фоновым (демоном). Демонические процессы автоматически завершаются при завершении основного процесса.

Метод start() не принимает дополнительных аргументов при вызове. Его возвращаемое значение всегда равно None. После вызова метод запускает новый процесс, активируя метод run() объекта в отдельном потоке выполнения.

Короткие примеры использования

Простой запуск функции без аргументов.

from multiprocessing import Process

def worker():
    print('Рабочий процесс')

if __name__ == '__main__':
    p = Process(target=worker)
    p.start()
    p.join()
Рабочий процесс

Запуск функции с позиционными и именованными аргументами.

from multiprocessing import Process

def calc(name, x, y):
    print(f'Процесс {name}: {x} + {y} = {x + y}')

if __name__ == '__main__':
    p = Process(target=calc, args=('Sum', 5, 3), kwargs={})
    p.start()
    p.join()
Процесс Sum: 5 + 3 = 8

Создание процесса-демона, который не будет завершен явно.

from multiprocessing import Process
import time

def daemon_worker():
    for i in range(3):
        print('Фоновая задача', i)
        time.sleep(0.5)

if __name__ == '__main__':
    p = Process(target=daemon_worker, daemon=True)
    p.start()
    time.sleep(0.6)  # Демон завершится с основным процессом
    print('Основной процесс завершен')
Фоновая задача 0
Фоновая задача 1
Основной процесс завершен

Похожие функции в Python

  • multiprocessing.Process.run() – метод, непосредственно выполняющий целевую функцию в текущем процессе, а не запускающий новый. Используется для переопределения логики выполнения в подклассах или отладки.
  • threading.Thread.start() – метод для запуска потока внутри одного процесса. Потоки разделяют память, что подходит для задач ввода-вывода, но не для CPU-операций из-за GIL.
  • concurrent.futures.ProcessPoolExecutor – высокоуровневый интерфейс для пула процессов. Предпочтителен при работе с множеством однотипных задач, требующих распараллеливания, так как управляет пулом и очередью задач.
  • os.fork() – низкоуровневый вызов Unix для создания копии процесса. Используется в специализированных сценариях, где требуется полный контроль над порождением процессов, но не является кроссплатформенным решением.

Аналоги в других языках программирования

Java: Класс Thread с методом start().

class MyThread extends Thread {
    public void run() {
        System.out.println("Поток запущен");
    }
}
public class Main {
    public static void main(String[] args) {
        MyThread t = new MyThread();
        t.start();
    }
}
Поток запущен

Go: Используется ключевое слово go для запуска горутины.

package main
import "fmt"
func worker() {
    fmt.Println("Горутина")
}
func main() {
    go worker()
    fmt.Println("Основная функция")
}
Основная функция
Горутина

JavaScript (Node.js): Модуль child_process с функцией spawn.

const { spawn } = require('child_process');
const child = spawn('echo', ['Hello from child process']);
child.stdout.on('data', (data) => {
    console.log(data.toString());
});
Hello from child process

C#: Класс System.Threading.Thread.

using System.Threading;
class Program {
    static void Worker() {
        System.Console.WriteLine("Поток C#");
    }
    static void Main() {
        Thread t = new Thread(Worker);
        t.Start();
    }
}
Поток C#

Отличия от Python заключаются в модели памяти: в Java и C# потоки разделяют память, как и в Python, но в Go и JavaScript (воркеры) изоляция сильнее. Также Python использует отдельные интерпретаторы в процессах, что обеспечивает лучшую изоляцию и обход GIL.

Типичные ошибки

Попытка повторного запуска процесса приводит к исключению.

from multiprocessing import Process

def task():
    pass

p = Process(target=task)
p.start()
p.start()  # Ошибка
RuntimeError: process already started

Передача невызываемого объекта в target вызывает исключение при запуске.

from multiprocessing import Process

p = Process(target=42)  # Число не является вызываемым объектом
p.start()
TypeError: 'int' object is not callable

Запуск процессов без защиты точки входа приводит к рекурсивному созданию процессов на некоторых платформах.

from multiprocessing import Process

def worker():
    print("Работа")

# Отсутствует if __name__ == '__main__':
p = Process(target=worker)
p.start()
На Windows может создаться бесконечное количество процессов.

Изменения в последних версиях

Начиная с Python 3.8, в модуле multiprocessing улучшена совместимость с контекстом запуска spawn по умолчанию на macOS. Это изменение повысило стабильность и безопасность при создании процессов. В более ранних версиях на macOS использовался метод fork, который мог приводить к сбоям в многопоточных программах.

В Python 3.4 появился параметр name в конструкторе Process, хотя фактически он поддерживался и ранее. Также с версии 3.3 процессы-демоны могут создаваться через аргумент daemon конструктора, а не только через присваивание атрибуту после создания.

Расширенные примеры использования

Запуск нескольких процессов с использованием очереди для обмена данными.

Пример python
from multiprocessing import Process, Queue

def square(numbers, q):
    for n in numbers:
        q.put(n * n)

if __name__ == '__main__':
    nums = [1, 2, 3, 4]
    q = Queue()
    p = Process(target=square, args=(nums, q))
    p.start()
    p.join()
    while not q.empty():
        print(q.get())
1
4
9
16

Использование блокировки для синхронизации доступа к общему ресурсу.

Пример python
from multiprocessing import Process, Lock
import time

def printer(item, lock):
    lock.acquire()
    try:
        time.sleep(0.1)
        print(item)
    finally:
        lock.release()

if __name__ == '__main__':
    lock = Lock()
    items = ['A', 'B', 'C']
    processes = []
    for item in items:
        p = Process(target=printer, args=(item, lock))
        processes.append(p)
        p.start()
    for p in processes:
        p.join()
A
B
C

Создание пользовательского класса процесса с переопределением метода run().

Пример python
from multiprocessing import Process

class CustomProcess(Process):
    def __init__(self, value):
        super().__init__()
        self.value = value
    def run(self):
        print(f'Запущен процесс с значением {self.value}')

if __name__ == '__main__':
    cp = CustomProcess(42)
    cp.start()
    cp.join()
Запущен процесс с значением 42

Использование общей памяти через Value и Array.

Пример python
from multiprocessing import Process, Value, Array

def modify(n, arr):
    n.value = 3.14
    for i in range(len(arr)):
        arr[i] = -arr[i]

if __name__ == '__main__':
    num = Value('d', 0.0)
    lst = Array('i', range(5))
    p = Process(target=modify, args=(num, lst))
    p.start()
    p.join()
    print(num.value)
    print(list(lst))
3.14
[0, -1, -2, -3, -4]

питон multiprocessing.Process.start function comments

En
Multiprocessing.Process.start Start the process's activity