Многопроцессное программирование Python и многопроцессное взаимодействие, передача данных

Python

Многопроцессное программирование и связь между процессамиПреимущества и недостатки многопроцессорности процесстри государства Пять состояний (новое состояние и состояние завершения добавляются на основе трех состояний)Приоритет процесса Характеристики процесса потерянный процесс процесс зомбипросить о понимании многопроцессное программированиеФункции, связанные с процессом многопроцессорный модульProcess() Создайте пользовательский унаследованный класс Process Технология пула процессов Функция пулаМежпроцессное взаимодействие (IPC) трубопроводная связьПример данных многопроцессного конвейера очередь сообщенийПример одного процесса Многопроцессорная очередь сообщений для передачи данных Общая память Сигнальная связь

 

Многопроцессное программирование и связь между процессами

  • Значение: максимально использовать ресурсы компьютера для повышения скорости работы программы.
  • Определение: цель использования нескольких ядер компьютера для одновременного выполнения нескольких задач с помощью прикладной программы, чтобы повысить скорость работы компьютера.
  • Схема реализации: многопроцессорная многопоточность
  • Параллелизм: компьютеры выполняют несколько задач одновременно.
  • Параллелизм: обработка нескольких задач одновременно, ядро ​​постоянно переключается между задачами, чтобы добиться эффекта того, что кажется, что они все еще обрабатывают операцию, но на самом деле ядро ​​может обрабатывать только одну из задач в определенный момент времени.

Преимущества и недостатки многопроцессорности

  • преимущество

    • Многоядерный компьютер может использоваться для одновременного выполнения задач для повышения эффективности выполнения.
    • Космическая независимость, безопасность данных
    • Запуск без влияния других процессов, простота создания
  • недостаток

    • Удаление и создание процессов потребляют много системных ресурсов

процесс

Посмотреть процесс:ps -auxПосмотреть дерево процессов:pstreeПросмотрите родительский процесс:ps -ajx

логотип название инструкция
S состояние ожидания прерываемое ожидание
D состояние ожидания непрерывное ожидание
T состояние ожидания приостановленное состояние
R рабочее состояние Включить состояние готовности
Z процесс зомби  
<   высокий приоритет
N   более низкий приоритет
l   с дочерним процессом
s   руководитель разговорной группы
+   процесс переднего плана

три государства

  • Состояние готовности: процесс имеет условия выполнения и ожидает, пока система выделит ресурсы.
  • Состояние выполнения: процесс занимает ЦП и находится в рабочем состоянии.
  • Состояние ожидания: процесс пока не имеет условий выполнения, блокирует ожидание и выполняется после выполнения условий.

Пять состояний (новое состояние и состояние завершения добавляются на основе трех состояний)

  • Новое состояние: процесс создания нового процесса и приобретения ресурсов
  • Состояние завершения: процесс, в котором выполнение процесса завершается, а ресурсы высвобождаются и перерабатываются.

Приоритет процесса

  • Роль: определяет разрешение на выполнение процесса.

  • Динамически просматривать информацию о процессах в системе:top,использовать< , >переворачивать страницы

    • Диапазон значений: -20 -- 19 -20 имеет наивысший приоритет
  • Запустить программу с указанным приоритетом

    • nice: указывает приоритет выполнения

      e.g. :nice -9 ./while.py--->> запустить с приоритетом -9

Характеристики процесса

  1. Процессы работают независимо друг от друга и работают независимо
  2. Процесс — это наименьшая единица распределения ресурсов операционной системы.
  3. Каждое пространство процесса независимо, каждое занимает определенный объем виртуальной памяти.

потерянный процесс

  1. Родительский процесс завершается раньше дочернего процесса, а дочерний процесс называется процессом-сиротой.
  2. Процесс-сирота будет принят процессом, указанным операционной системой, и системный процесс станет родительским процессом для процесса-сироты.

процесс зомби

  1. Дочерний процесс завершается раньше родительского процесса, но родительский процесс не обрабатывает статус выхода дочернего процесса, тогда дочерний процесс станет зомби-процессом.
  2. Зомби-процессы будут хранить в памяти небольшой объем информации о печатной плате, большое количество зомби-процессов будет потреблять системные ресурсы, и следует избегать генерации зомби-процессов.
  • Как избежать порождения процессов-зомби

    • Обработка статуса выхода дочернего процесса

      pid, status = os.wait()

       

      Функция: заблокировать родительский процесс и дождаться выхода дочернего процесса.

      возвращаемое значение:

просить о понимании

  1. Что такое процесс?
  2. Понимание характеристик процесса
  3. Очистите каждое состояние процесса,

многопроцессное программирование

 
 1  
 2   
 3 # 功能 : 创建新的进程
 4 # 参数 : 无
 5 # 返回值 : 失败--->返回一个负数
 6 #  成功--->在新的进程中返回 ‘0’
 7 # 在原有的进程中返回新的进程的PID号
 8 import os
 9 pid = os.fork()
10 pid = os.fork()
11 print(pid)
12 ​
13 '''打印
14 9352
15 0
16 9353
17 '''

 

  • Дочерний процесс скопирует весь код родительского процесса, включая пространство памяти, сгенерированное до форка.
  • Дочерний процесс начинает выполняться со следующего предложения форка, не мешая родительскому процессу.
  • Порядок выполнения родительского и дочернего процессов не обязательно, родительский и дочерний процессы используют общий дисплей терминала.
  • Родительский и дочерний процессы обычно выбирают выполнение разного кода на основе разницы в возвращаемом значении fork. Таким образом, структура if почти стандартна для форка.
  • Пространства родительского и дочернего процессов независимы, и операции являются содержимым этого пространства, не влияя друг на друга.
  • Подпроцессы также имеют свои характеристики, такие как номер PID, печатная плата, набор команд и т. д.

Функции, связанные с процессом

функциональный метод параметр инструкция
os.getpid()   Возвращает номер PID текущего процесса
os.getppid()   Возвращает номер PID родительского процесса текущего процесса
os._exit( status ) статус выхода из программы выход из процесса
sys.exit( [ status ] ) Число: указывает статус выхода, если не написано, по умолчанию выход из процесса
  
import os
pid = os.fork()
if pid < 0:
    print("创建进程失败")
elif pid == 0:
    print("子进程我的真实PID为:",os.getpid(),"我的父进程PID为:",os.getppid())
else:
    print("我是父进程执行的代码,当前的变量pid为:",pid,"我的真实PID为:",os.getpid())
    
'''打印内容''''''
我是父进程执行的代码,当前的变量pid为: 10992 我的真实PID为: 10991
子进程我的真实PID为: 10992 我的父进程PID为: 10991
''''''打印内容'''
    
# 如果pid 10992和子进程真实PID不同,那么这个子进程就变成了孤儿进程

 

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

import multiprocessing

from multiprocessing import Process

Process()

  • Функции: создать объект процесса

  • параметр

    • имя: имя процесса
    • цель: функция привязки
    • args: кортеж, передать параметры целевой функции по позиции
    • kwargs: словарь, передает параметры целевой функции в соответствии с парами ключ-значение
    • name: строка, имя нового процесса
    • Например: p = Process(target = fun,args=(a,b))
функциональный метод инструкция
p.start() Запускаем процесс, целевая функция выполняется автоматически, а процесс в это время фактически создается
p.join([timeout]) Блок, ожидающий перезапуска дочернего процесса, тайм-аут — это время ожидания
p.is_alive() Судите о состоянии жизненного цикла процесса, в жизненном цикле возвращайте логическое значение
p.name() получить имя процесса
p.pid() Получить pid процесса
p.daemon() Состояние по умолчанию — False, и выход основного процесса не влияет на дочерний процесс. True : дочерний процесс заканчивается основным процессом
  • Используйте многопроцессорность для создания дочернего процесса. Аналогично, дочерний процесс копирует весь код родительского процесса. Выполнение родительского и дочернего процессов не влияет друг на друга, а родительский и дочерний процессы имеют свое собственное пространство для выполнения.

  • Если вы не используете соединение для волны дочернего процесса, дочерний процесс станет зомби-процессом после выхода.

from multiprocessing import Process 
from time import sleep 
​
#带参数的进程函数
def worker(sec,name):
    for i in range(3):
        sleep(sec)
        print("I'm %s"%name)
        print("I'm working...")
​
p = Process(target = worker,args = (2,),\
    kwargs = {'name':'Daivl'},name = "Worker")
p.start()
​
print("Process name:",p.name) #进程名称
print("Process PID:",p.pid) #获取进程PID
​
#进程alive情况
print("Process is alive:",p.is_alive())
​
p.join(3)
print("==================")

 

 

 

Создайте пользовательский унаследованный класс Process

  1. Наследовать процесс

  2. написать свой собственный__init__, при загрузке родительского класса__init__метод

  3. переписатьrunметод, который можно запустить автоматически, вызвав start для сгенерированного объекта

from  import Process
import time
​
class ClockProcess(Process):
​
    def __init__(self,value):
        self.value = value
        super(ClockProcess,self).__init__()
​
    def run(self):
        for i in range(5):
            print("现在的时间是",time.ctime())
            time.sleep(self.value)
​
# 创建自定义进的类的对象
p =ClockProcess(2)
​
# 自动调用run
p.start()
p.join()    

 

Технология пула процессов

  • причина

    • Если есть большое количество задач, которые должны быть выполнены несколькими процессами. Ему необходимо часто создавать и удалять процессы, что увеличивает потребление ресурсов компьютера.
  • принцип

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

    1. Создайте пул процессов и поместите соответствующий процесс в пул
    2. Добавить событие в очередь ожидания событий
    3. Продолжайте считать время выполнения процесса, пока все процессы не будут выполнены
    4. Закройте пул процессов и перезапустите процесс

Функция пула

  • Pool(Processes)

    • Функция: создание объекта пула процессов
    • Указывает, сколько процессов находится в пуле процессов
  • pool.apply_async(func, args, kwds)

    • Функция: поместить время в очередь пула процессов

    • параметр

      • func: функция события
      • args: передать аргументы функции в виде кортежа
      • kwds : передать параметры в func в виде словаря
    • возвращаемое значение объект

  • pool.apply(func, args, kwds)

    • Функция: поместить время в очередь пула процессов

    • параметр

      • func: функция события
      • args: передать аргументы функции в виде кортежа
      • kwds : передать параметры в func в виде словаря
  • pool.close()

    • Функция: закрыть пул процессов
  • pool.join()

    • Функция: Переработка пула процессов
  • pool.map(func,iter)

    • Функция: поместить событие, которое должно быть выполнено, в пул процессов.

    • параметр

      • func : функция для выполнения
      • iter : итерируемый объект
    • Возвращаемое значение: столбец результатов нескольких возвратов

from multiprocessing import Process
import time
​
class ClockProcess(Process):
​
    def __init__(self,value):
        self.value = value
        super(ClockProcess,self).__init__()
​
    def run(self):
        for i in range(5):
            print("现在的时间是",time.ctime())
            time.sleep(self.value)
​
# 创建自定义进的类的对象
p =ClockProcess(2)
​
# 自动调用run
p.start()
p.join()    

 

Межпроцессное взаимодействие (IPC)

Методы межпроцессного взаимодействия: каналы, очереди сообщений, разделяемая память, сигналы, семафоры, сокеты.

  трубопровод очередь сообщений Общая память
открыть пространство ОЗУ ОЗУ ОЗУ
прочти и напиши Чтение и запись на обоих концах [двунаправленный/однонаправленный] первым пришел-первым вышел перезаписать предыдущий контент
эффективный в целом в целом выше
применение В основном используется для родительских и дочерних процессов Широкий и гибкий Требуется взаимное исключение

 

трубопроводная связь

Принцип связи:Откройте пространство конвейера в памяти, создайте объекты операций конвейера, и несколько процессов используют «один и тот же» объект конвейера для работы для достижения связи.

multiprocessing --> Pipe

  • fd1,fd2 = Pipe(duplex = True)

    • Функция: создать конвейер

    • параметр

      • По умолчанию представлен двунаправленным каналом.
      • Установите значение False, чтобы использовать канал с односторонним движением.
    • возвращаемое значение

      • Если это двунаправленный канал, оба могут читать и писать
      • Если это односторонний канал, fd1 доступен только для чтения, а fd2 только для записи.
  • fd.recv()

    • Функция: чтение информации из трубы
    • Возвращаемое значение: прочитать содержимое
    • Блокировать, если труба пуста
  • fd.send(data)

    • Функция: запись контента в канал
    • Параметры: что писать
    • Может отправлять произвольные типы данных Python

Пример данных многопроцессного конвейера

from multiprocessing import Process,Pipe
import time,os
​
# 创建管道对象
fd1, fd2 = Pipe()
​
def fun(name):
    time.sleep(1)
    fd2.send(os.getppid())
​
jobs = []
# 创建5个子进程
for i in range(5):
    p = Process(target = fun,args = (i,))
    jobs.append(p)
    p.start()
​
for i in range(5):
    data = fd1.recv()
    print(data)
​
for i in jobs:
    i.join()

 

 

очередь сообщений

Очередь: первый пришел, первый ушел, по порядку

Принцип связи: построить модель структуры данных очереди в памяти. Несколько процессов могут хранить контент в очереди, и порядок, в котором контент извлекается, соответствует порядку, в котором он хранится.

  • Создать очередь

    q = Queue(maxsize = 0)

    • Функция: создать очередь сообщений
    • Параметры: указывает максимальное количество сообщений для хранения. По умолчанию означает выделение хранилища в соответствии с памятью
    • Возвращаемое значение: объект очереди
  • q.put(data, [block, timeout])

    • Функция: хранить сообщения как очередь

    • параметр

      • data: контент, который нужно сохранить
      • block: по умолчанию очередь будет заблокирована, когда она заполнена.Если установлено значение False, она не будет заблокирована.
      • тайм-аут: тайм-аут
  • data = q.get([block, timeout])

    • Функция: получить сообщение очереди

    • параметр

      • block: по умолчанию очередь будет заблокирована, когда она пуста.Если установлено значение False, она не будет блокироваться.
      • тайм-аут: тайм-аут
    • Возвращаемое значение: вернуть извлеченное содержимое

  • q.full(): определить, заполнена ли очередь

  • q.empty(): определить, пуста ли очередь

  • q.size(): определить количество сообщений в очереди

  • q.close: закрыть очередь

Пример одного процесса

#!《 单进程 》
from multiprocessing import Queue
from time import sleep
​
# 创建队列,可以放3条消息
q = Queue(3)
# 存一条消息
q.put(1)
sleep(0.5)
# 判断队列是否为空
print(q.empty())
q.put(2)
# 判断队列是否满
print(q.full())
q.put(3)
# 输出队列消息数量
print(q.qsize())
# 输出
print(q.get())
q.close()

 

 

Многопроцессорная очередь сообщений для передачи данных

from multiprocessing import Queue,Process
from time import sleep
​
# 创建队列,可以放3条消息
q = Queue(3)
​
def fun1():
    sleep(1)
    q.put({"a":1,"b":2})
​
def fun2():
    sleep(2)
    print("收到消息",q.get())
​
p1 = Process(target = fun1)
p2 = Process(target = fun2)
p1.start()
p2.start()
p1.join()
p2.join()

 

 

 

Общая память

Принцип связи: откройте пространство в памяти, видимое для нескольких процессов, процессы могут писать и читать, но содержимое, записываемое каждый раз, перезаписывает предыдущее содержимое.

Можно отправлять только отдельные данные

  • obj = Value(ctype, obj)

    • Функция: открыть пространство общей памяти

    • параметр

      • ctype: тип данных для хранения
      • obj: начальные данные разделяемой памяти
    • Возвращаемое значение: объект общей памяти

    • obj.valueТо есть значение общей памяти, которое можно изменить, чтобы изменить память.

    • from multiprocessing import Value
      from time import sleep
      import os
      # 创建共享内存对象
      money = Value('i',2000)
      ​
      # 操作共享内存
      def deposite():
          while True:
              i = int(input("请输入:"))
              money.value = i
              sleep(0.05)
      ​
      def withdraw():
          data = money.value
          while True:
              if data != money.value :
                  data = money.value
                  print(data)
                  
      pid = os.fork()
      if pid == 0 :
          deposite()
      withdraw() 
  • obj = Array(ctype, obj)

    • Функция: открыть пространство общей памяти

    • параметр:

      • ctype: формат данных для хранения
      • obj: Инициализировать сохраненное содержимое, такое как списки и строки. Если это число, оно представляет собой количество открытых пространств памяти.
    • Возвращаемое значение: возвращает объект общей памяти, по которому можно пройти

    • from multiprocessing import Array,Process
      from time import sleep
      import os
      ​
      # 开辟100字符内存空间,'c'代表字符,'i'代表整形
      shm = Array('c',100)
      # 必须使用字节流
      shm.value = "哈哈哈".encode()
      def fun1():
          print(os.getpid(),"子进程1:",shm.value.decode())
          shm.value = "夜夜夜".encode()
      ​
      def fun2():
          sleep(1)
          print(os.getpid(), "子进程2:",shm.value.decode())
      ​
      p1 = Process(target = fun1)  
      p2 = Process(target = fun2)
      p1.start()
      p2.start()
      p1.join()
      p2.join()
      ​
      ​

       

Сигнальная связь

Процесс посылает сигнал другому процессу, чтобы передать какую-то информацию, и получатель делает что-то в соответствии с переданной информацией.

$ kill -lПросмотр описания системных сигналов

$ kill -9 pid号отправить сигнал процессу

Название сигнала инструкция    
1) SIGHUP Отключить    
2) SIGINT ctrl+c    
3) SIGQUIT ctrl+\    
20) SIGTSTP ctrl+z    
9) SIGKILL убить процесс    
19) SIGSTOP Приостановить процесс    
26) SIGVTALRM тактовый сигнал    
17) SIGCHLD Сигнал, отправляемый родительскому процессу при выходе из дочернего процесса    
       

в Питонеimport signalМожет получить сигнал

  • os.kill(pid, sig)

    • Функция: отправить сигнал

    • параметр

      • pid: номер PID для отправки сигнала
      • sig : имя сигнала
import os
import signal
os.kill(12345,signal.SIGKILL) #杀死进程
автор:Banl
Источник:www.cnblogs.com/BanL/ ----------------------------------------------------------------------

Персонализированная подпись: Gou Rixin, Ri Rixin и Rixin!

Если эта статья была вам полезна, не забудьте нажать «Рекомендовать» в правом нижнем углу, спасибо!