Подтвердить что ты не робот

Как параллельно обрабатывать данные в файле с отображением памяти

Как указывается имя файла с отображением памяти, я понимаю, что часть большого файла может быть отображена в память с использованием класса MemoryMappedFile в С# для быстрого процесса обработки данных. То, что я хотел бы сделать с файлом, связанным с памятью, - это параллельная обработка отображаемой памяти. Для этого у меня есть следующие вопросы.

  • Является MemoryMappedFileViewAccessor потокобезопасным и Parallel.For-safe? Я действительно сделал демо-программу, чтобы проверить вопрос, и, похоже, он работает. Но не могу найти никаких ссылок на это. Если да, я готов. В противном случае,
  • Есть ли способ прямого доступа к памяти, сопоставленной с массивом? Я знаю, что MemoryMappedFileViewAccessor имеет метод ReadArray, но использование метода - это дублирование памяти.
4b9b3361

Ответ 1

Вы можете это рассудить. Файл с отображением памяти - это всего лишь кусок памяти в вашей программе, чьи байты доступны более чем одним процессом. Они довольно неудобны в управляемом коде, поскольку этот фрагмент существует по определенному адресу. Для этого требуется доступ к данным с помощью указателя, они являются табу в управляемом коде. MemoryMappedFileViewAccessor обертывает этот указатель, он копирует данные из управляемой памяти в общую память. Обратите внимание, что это побеждает основную причину использования MMF и почему их поддержка так долго появлялась в .NET. Убедитесь, что вы не хотите использовать именованные каналы.

Поэтому, рассуждая об этом, MMF, конечно, не является потокобезопасным по дизайну, поскольку это общая память, так же как и глобальные переменные в вашем коде. Все происходит неправильно точно так же, если потоки читают и записывают один и тот же раздел разделяемой памяти. И вы должны защищать от этого точно так же, как и блокировку, чтобы гарантировать, что только один поток может получить доступ к общему разделу.

Также обратите внимание, что вам необходимо реализовать эту блокировку между процессами, которые читают и записывают MMF. Который имеет тенденцию быть болезненным, вам нужно использовать именованный мьютекс, который создает "главный" процесс, и открывается "подчиненный" процесс. Вы не можете сэкономить на этом требовании блокировки. Примечательно, что вы никогда не говорили об этом в своем вопросе, поэтому там есть Красный флаг.

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

Ответ 2

Внутри памяти MemoryMappedViewAccessor выводится из UnmanagedMemoryAccessor, который кажется неизменным, хотя и не имеет полей readonly - по крайней мере, он не изменяет существующие поля во время операций чтения/записи, что делает его потокобезопасным. В свою очередь, он считывает данные с отображением памяти из класса SafeBuffer, который содержит следующий текст в заголовок комментариев:

/* Keep the penalties for using this class small, both in terms of space 
// and time.  Having multiple threads reading from a memory mapped file
// will already require 2 additional interlocked operations.  If we add in 
// a "current position" concept, that requires additional space in memory and 
// synchronization.  Since the position in memory is often (but not always)
// something that can be stored on the stack, we can save some memory by 
// excluding it from this object.  However, avoiding the need for
// synchronization is a more significant win.  This design allows multiple
// threads to read and write memory simultaneously without locks (as long as
// you don't write to a region of memory that overlaps with what another 
// thread is accessing).

Итак, я предполагаю, что операции с файлами с отображением памяти являются потокобезопасными, хотя странно, что в MSDN нет подтверждения.

Ответ 3

1) MSDN указывает как для MemoryMappedFile, так и MemoryMappedViewAccessor, что:

Все публичные статические (Shared in Visual Basic) члены этого типа являются потокобезопасными. Любые члены экземпляра не гарантируют безопасность потоков.

2) точка MemoryMappedFile не должна уменьшать выделение памяти. Если вы читали файл с диска, вам нужно было бы выделить память для хранения элементов, которые вы читали из файла. Это также относится к файлу с отображением памяти, а также