Общая координация mmap с использованием блокировок fcntl?
-
25-09-2019 - |
Вопрос
При использовании mmap()
для общей памяти (из Linux или других UNIX-подобных систем) возможно ли (и переносимо) использовать fcntl()
(или flock()
или lockf()
функции) для координации доступа к отображению?
Ответы на это ТАКОЙ вопрос кажется, это наводит на мысль, что это должно сработать.
Идея, которую я имею в виду, состояла бы в том, чтобы структурировать общую память с помощью карты процесс / страница, чтобы свести к минимуму конфликт блокировок.Каждый процесс мог бы работать со своими страницами одновременно, и блокировку нужно было бы устанавливать только при обновлении сопоставлений процесс / страница.(Доступ на чтение с неизвестных страниц будет включать проверку серийного номера, копирование нужных данных, а затем проверку того, что серийный номер этого блока не изменился).
Концептуально каждый процесс, совместно использующий это сопоставление файлов, выполнял бы mmap()
, найдите в нем свободный блок, получите блокировку области процесса / страницы, обновите ее своим собственным назначением, снимите блокировку и затем весело продолжайте свою работу.Любой процесс может выполнять поиск устаревших сопоставлений (используя kill()
с нулем в качестве сигнала) и очистите сопоставление таблицы процесс / страница.
(Грубо говоря, в общих чертах, я играю с механизмом обработки данных производителя / потребителя, использующим общую память из Python поверх Linux;Я бы хотел, чтобы решение было переносимым на BSD и другие языки программирования - при условии, что поддержка mmap()
и необходимые интерфейсы для fcntl()
, flock()
или lockf().
Мне также было бы интересно получить псевдокод, показывающий, как можно измерить конфликт блокировок и обнаружить любые сбои синхронизации.Я отдаю себе отчет в том, что нарезание резьбы и многопроцессорная обработка с их соответствующими Queue()
объекты - это самый простой способ реализации модели обработки Python producer / consumer).
Решение
Я уверен, что блокировки обеспечат взаимное исключение, но я не знаю, создадут ли они вам барьер памяти.Похоже, что переход в ядро (что будут делать fcntl, flock и lockf), скорее всего, приведет к что - то это приводит к нарушению порядка чтения и записи в память для фиксации, но я сомневаюсь, что вы получите твердую гарантию.Я думаю, что это одна из тех вещей, где это, вероятно, работает, и тестирование покажет, что это действительно работает, но вы не будете знать, что это всегда работает, пока не найдете ссылку, говорящую об этом.
Я сделал что-то похожее на это из C, но я использовал атомарные блокировки в самой общей памяти.Раньше вам приходилось выполнять небольшую встроенную сборку, но теперь в gcc есть некоторые встроенные операции, которые вы можете использовать:
http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html
Если вы хотите написать очень простое расширение Python, вы могли бы обернуть __sync_lock_test_и_set(...) и __sync_lock_release(...), чтобы сделать то, что вам нужно.Они должны быть довольно портативными.
Я полагаю, что есть способ поместить мьютексы pthread и в разделяемую память, но у меня нет никакого опыта в этом.Опять же, вам пришлось бы написать простое расширение C, чтобы получить доступ к нему из Python.