multiprocessing.RawArray операция - PullRequest
       18

multiprocessing.RawArray операция

1 голос
/ 07 июня 2019

Я читал, что RawArray может быть разделен между процессами без копирования, и хотел понять, как это возможно в Python.

Я видел в sharedctypes.py , что RawArray создается из BufferWrapper из heap.py , затем обнуляется с помощью ctypes.memset.

BufferWrapper сделан из объекта Arena, который сам построен из mmap (или 100 mmaps в окнах, см. Строку 40 в heap.py )

Я прочитал, что системный вызов mmap фактически используется для выделения памяти в Linux / BSD, а модуль Python использует MapViewOfFile для окон.

mmap тогда кажется удобным. Кажется, он может работать напрямую с mp.pool -

from struct import pack
from mmap import mmap

def pack_into_mmap(idx_nums_tup):

    idx, ints_to_pack = idx_nums_tup
    pack_into(str(len(ints_to_pack)) + 'i', shared_mmap, idx*4*total//2 , *ints_to_pack)


if __name__ == '__main__':

    total = 5 * 10**7
    shared_mmap = mmap(-1, total * 4)
    ints_to_pack = range(total)

    pool = Pool()
    pool.map(pack_into_mmap, enumerate((ints_to_pack[:total//2], ints_to_pack[total//2:])))

Мой вопрос -

Откуда модуль многопроцессорной обработки узнает, что не копирует объект RawArray на основе mmap между процессами, как это происходит с "обычными" объектами python?

1 Ответ

1 голос
/ 08 июня 2019

[Python 3.Docs]: многопроцессорная обработка - параллелизм на основе процессов сериализует / десериализует данные, которыми обмениваются процессы, используя собственный протокол: [Python 3.Docs]: pickle - сериализация объектов Python (и отсюда условия: маринованные / маринованные ).

Согласно [Python 3.Docs]: pickle - объект. __ getstate __ () :

Классы могут далее влиять на то, как их экземпляры травятся; если класс определяет метод __ getstate __ () , он вызывается и возвращаемый объект выбирается как содержимое для экземпляра, а не как содержимое словаря экземпляра. Если метод __ getstate __ () отсутствует, экземпляр __ dict __ как обычно протравливается.

Как видно из ( Win вариант) Arena.__getstate__, (цепочка классов: sharedctypes.RawArray -> heap.BufferWrapper -> heap.Heap -> heap.Arena), только метаданные ( name и size ) являются маринованными для экземпляра Arena , но не для самого буфера.

И наоборот, в __ setstate __ буфер строится на основе (приведенных выше) метаданных.

...