Общая координация mmap с использованием замков fcntl?

При использовании mmap() для разделяемой памяти (из Linux или других UNIX-подобных систем) возможно ли (и переносимо) использовать fcntl() (или функции flock() или lockf()) для координации доступа к отображению?

Ответы на этот вопрос SO кажется, что это должно работать.

Идея, которую я имею в виду, состоит в том, чтобы общая память была структурирована с помощью карты процесса/страницы, чтобы свести к минимуму конфликты при блокировке. Процессы могли бы работать со своими страницами одновременно, и блокировку нужно было бы получить только при обновлении сопоставлений процессов и страниц. (Доступ на чтение с не принадлежащих страниц будет включать проверку серийного номера, копирование нужных данных, а затем проверку того, что серийный номер этого блока не изменился).

Концептуально каждый процесс, совместно использующий это сопоставление файлов, будет выполнять mmap(), находить в нем свободный блок, получать блокировку области процесса/страницы, обновлять ее своим собственным назначением, снимать блокировку и затем весело продолжать свою работу. Любой процесс может искать устаревшие сопоставления (используя kill() с нулем в качестве сигнала) и очищать сопоставление таблицы процесс/страница.

(Грубо говоря, я играю с механизмом обработки производитель/потребитель, использующим общую память из Python по сравнению с Linux; я хотел бы, чтобы решение было переносимым на BSD и на другие языки программирования --- до тех пор, пока поддержка mmap() и необходимые интерфейсы для fcntl(), flock() или lockf().. Мне также был бы интересен псевдокод, показывающий, как можно измерять конфликты блокировок и обнаруживать любые сбои синхронизации. Я знаю, что threading и многопроцессорная обработка с их соответствующими Queue() объектами — самый простой способ реализовать модель обработки Python-производителя/потребителя).


person Jim Dennis    schedule 10.05.2010    source источник


Ответы (1)


Я уверен, что блокировки обеспечат взаимное исключение, но я не знаю, дадут ли они вам барьер памяти. Кажется, что переход к ядру (что сделают fcntl, flock и lockf), скорее всего, сделает что-то, что заставит зафиксировать неупорядоченное чтение и запись памяти, но я сомневаюсь, что вы получите жесткая гарантия. Я думаю, что это одна из тех вещей, где это, вероятно, работает, и тестирование покажет, что это работает, но вы не будете знать, что это всегда работает, пока не найдете ссылку, говорящую об этом.

Я сделал что-то похожее на C, но использовал атомарные спин-блокировки в самой разделяемой памяти. Раньше вам приходилось выполнять небольшую встроенную сборку, но теперь у gcc есть некоторые встроенные операции, которые вы можете использовать:

http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html

Если вы хотите написать очень простое расширение Python, вы можете обернуть __sync_lock_test_and_set(...) и __sync_lock_release(...), чтобы делать то, что вам нужно. Они должны быть довольно портативными.

Я считаю, что есть способ поместить мьютексы pthread в общую память, но у меня нет в этом никакого опыта. Опять же, вам придется написать простое расширение C, чтобы получить доступ к этому из Python.

person xscott    schedule 27.11.2010
comment
На самом деле нет необходимости писать расширение Python. Вы можете использовать модуль Python ctypes, чтобы подключиться к библиотеке C напрямую через код Python. (Вам все еще нужно достаточное количество знаний о C, хотя) - person intgr; 12.01.2011