Почему Linux может принимать сокеты в многопроцессорности?

Этот код отлично работает в Linux, но не работает под Windows (что ожидается). Я знаю, что многопроцессорный модуль использует fork() для создания нового процесса, и файловые дескрипторы, принадлежащие родительскому объекту (то есть открытый сокет), поэтому унаследованы дочерним элементом. Тем не менее, я понимаю, что единственный тип данных, которые вы можете отправлять посредством многопроцессорной обработки, должен быть разборчивым. В Windows и Linux объект сокета не является подходящим.

 from socket import socket, AF_INET, SOCK_STREAM import multiprocessing as mp import pickle sock = socket(AF_INET, SOCK_STREAM) sock.connect(("www.python.org", 80)) sock.sendall(b"GET / HTTP/1.1\r\nHost: www.python.org\r\n\r\n") try: pickle.dumps(sock) except TypeError: print("sock is not pickleable") def foo(obj): print("Received: {}".format(type(obj))) data, done = [], False while not done: tmp = obj.recv(1024) done = len(tmp) < 1024 data.append(tmp) data = b"".join(data) print(data.decode()) proc = mp.Process(target=foo, args=(sock,)) proc.start() proc.join() 

Мой вопрос заключается в том, почему объект socket , явно непродуманный объект, должен быть передан с многопроцессорной обработкой? Разве это не использует рассол, как делает Windows?

2 Solutions collect form web for “Почему Linux может принимать сокеты в многопроцессорности?”

На платформах unix сокеты и другие файловые дескрипторы могут быть отправлены в другой процесс с использованием сокетов unix domain (AF_UNIX), поэтому сокеты можно травить в контексте многопроцессорности.

Модуль многопроцессорности использует специальный экземпляр сортировочного устройства вместо обычного pickler, ForkingPickler , для рассортирования сокетов и дескрипторов файлов, которые затем могут быть разбросаны в другом процессе. Это можно сделать только потому, что известно, что маринованный экземпляр будет разбросан, не имеет смысла рассортировать сокет или файловый дескриптор и отправлять его между границами машины.

Для окон существуют аналогичные механизмы для открытых дескрипторов файлов.

Я думаю, проблема заключается в том, что для multiprocessing используется другой сортировщик для систем Windows и других ОС. В Windows нет реальной fork() , и травление, которое выполняется, эквивалентно травлению через границы машины (т.е. распределенные вычисления). В системах, отличных от Windows, объекты (например, дескрипторы файлов) могут быть разделены между границами процесса. Таким образом, травление на системах Windows (с pickle ) является более ограниченным.

В пакете multiprocessing используется copy_reg для регистрации нескольких типов объектов для pickle , а один из этих типов – socket . Однако сериализация объекта socket который используется в Windows, более ограничена из-за слабой разборчивости Windows.

В соответствующей заметке, если вы хотите отправить объект socket с multiprocessing в Windows, вы можете … вам просто нужно использовать multiprocess пакет, который использует dill вместо pickle . dill имеет лучший сериализатор, который может разжевывать объекты socket на любой ОС и, таким образом, отправляет объект socket с multiprocess работами в любом случае.

dill имеет функцию copy ; в основном loads(dumps(object)) которые полезны для проверки объекта, могут быть сериализованы. dill также имеет check , который выполняет copy но с более ограничительной вилкой типа «Windows». Это позволяет пользователям в системах, отличных от Windows, эмулировать copy в системе Windows или распределенных ресурсах.

 >>> import dill >>> import socket >>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) >>> s.connect(('www.python.org', 80)) >>> s.sendall(b'GET / HTTP/1.1\rnHost: www.python.org\r\n\r\n') >>> >>> dill.copy(s) <socket._socketobject object at 0x10e55b9f0> >>> dill.check(s) <socket._socketobject object at 0x1059628a0> >>> 

Короче говоря, разница вызвана сортировщиком, который использует multiprocessing в Windows, отличной от сортировочной машины, используемой в системах, отличных от Windows. Тем не менее, можно (и легко) работать над любой ОС, используя лучший сериализатор (как используется в multiprocess ).

  • Как закрыть сокет, оставленный открытым убитой программой?
  • данные сокетов процесса, которые заканчиваются разрывом строки
  • Как обратиться к стандартной библиотеке в файле конфигурации ведения журнала?
  • Python SocketServer: отправка нескольким клиентам?
  • Туннелирование httplib через прокси-сервер
  • OSError: Плохой дескриптор файла в python 3
  • Синхронизация потоков в Python
  • Как сделать простой многопоточный сервер сокетов в Python, который запоминает клиентов
  •  
    Interesting Posts for Van-Lav

    Как предотвратить неисправную трубу errno 32?

    Tornado Python как демон

    Список всех тестов, найденных Nosetest

    Использование ARPACK для решения проблемы собственных значений, но получение несогласованных результатов с Matlab

    Проверьте, присутствует ли атрибут в теге в BeautifulSoup

    Как изменить имя приложения в строке меню OSX в наборе приложений с чистым Python?

    Должно ли использование памяти увеличиваться при использовании ElementTree.iterparse () при очистке () деревьев?

    Regex соответствует цифрам определенной длины

    PyQt lineEdit пуст при вызове из другого скрипта

    Поле множественного выбора доступа в колбе

    тестирование тегов без содержимого с помощью красивого питона python

    NeedIndexError в Google App Engine навсегда

    Оптимизация SciPy сгруппированными границами

    Проблема с Python: невозможно найти vcvarsall.bat

    В чем разница между функциями перекоса и эксцесса в пандах против скупых?

    Python - лучший язык программирования в мире.