Отображение памяти удаленных файлов

#sockets #systems-programming #memory-management

#сокеты #системы-программирование #управление памятью

Вопрос:

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

 // Type definition for remote file location
struct fileloc {
    struct in_addr ipaddress; // Remote IP
    int port;                 // Remote port
    char *pathname;           // Remote file to be memory mapped
};
typedef struct fileloc fileloc_t;

// Create a new memory mapping in the virtual address space of the calling process          
// location: Remote file to be memory mapped
void *rmmap(fileloc_t location, off_t offset);

// Deletes mapping for the specified address range
// addr:   Address returned by mmap
int rmunmap(void *addr);

// Attempt to read up to count bytes from memory mapped area pointed
// to by addr   offset into buff
ssize_t mread(void *addr, off_t offset, void *buff, size_t count);

// Attempt to write up to count bytes to memory mapped area pointed
// to by addr   offset from buff
ssize_t mwrite(void *addr, off_t offset, void *buff, size_t count);
  

Я сталкиваюсь с некоторыми проблемами проектирования. Вот о чем я подумал:

  • Клиент в первый раз вызывает rmmap() , предварительно определяя местоположение сервера и запрошенный файл, а также смещение.Сервер возвращает клиенту фиксированный фрагмент файла.
  • сервер примет к сведению, какой клиент запрашивал какой фрагмент файла. Он также сохранит таблицу идентификаторов клиентов, rquested смещений и статус флага (заблокирован или нет). Обработка конфликтов относится к этой таблице.
  • функции чтения и записи будут использоваться локально на клиенте и не будут подключены к серверу. (хотя мне интересно, возможно ли подключиться к серверу перед записью, чтобы клиент мог записывать только тогда, когда никто не читает).
  • unmap() будет использоваться для «фиксации» изменений на сервере.

Я все еще не уверен в блокировке файлов и разрешении конфликтов, однако я на правильном пути?

Ответ №1:

Я все еще не уверен в блокировке файлов и разрешении конфликтов

В дополнение к API вам нужно будет определить протокол для передач, вероятно, тот, который является внутренним (т. Е. Реализован в библиотеке и не прозрачен для пользователя, так как TCP реализован внутренне по отношению к socket() ). Клиенту необходимо будет поддерживать постоянное соединение и активно обрабатывать входящие сообщения с сервера. Эти сообщения будут соответствовать записям, выполненным другими подключенными клиентами, т. Е. Они являются обновлениями карты.

Когда клиент A отправляет запись на сервер, если в это местоположение только что была записана запись клиентом B, а клиент A не подтвердил получение обновления относительно этого, вы возвращаете ошибку клиенту A.

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

Комментарии:

1. понятно. Как я могу отправить на сервер, используя read() и write() без struct fileloc передачи в качестве параметра?

2. Вот где вам нужно реализовать API и при этом разработать протокол передачи или, по крайней мере, некоторые его аспекты. Если вы отвечаете за работающие сервер и клиент, вам нужно будет использовать соответствующий протокол транспортного уровня , например TCP, и строить поверх этого, но API может ограничиться определением структур данных и некоторыми абстракциями о протоколе клиент / сервер.

Ответ №2:

Задача является открытой, поэтому допустимо множество возможных реализаций. Основное замечание, которое противоречит вашему выбору, заключается в том, что в реальной среде требуется mmap файл, который не помещается в системную память. Если бы я был учителем, я бы попросил об этом. Итак, измените свой дизайн, чтобы это работало:

  • чтение и запись будут выполняться локально, когда это возможно, или при необходимости заменят локальный фрагмент новым, заменяя множество фрагментов по мере выполнения всего чтения или записи.

Поведение блокировки полностью «не определено» в проблеме. Тривиальный случай заключается в том, что каждый клиент имеет эксклюзивную блокировку для каждого файла, извлекаемого во время mmaping. Менее тривиальный случай блокирует диапазоны блоков при чтении и записи. Блокировка отдельных блоков проста и может быть реализована в результате чтения и записи с сервера, но каждое чтение и запись не будут атомарными во всем диапазоне блоков. Обратите внимание, что расширенная блокировка не запрашивается. API недостаточно для объявления эксклюзивных или совместно используемых блокировок.