Вход/Регистрация
UNIX: взаимодействие процессов
вернуться

Стивенс Уильям Ричард

Шрифт:

Memory fault (coredump)

alpha % ls -l foo

– rw-r-r– 1 rstevens operator 5000 Mar 21 08:40 foo

Мы все так же можем обратиться к памяти за пределами отображенного файла, но не выходя за грaницы страницы памяти (индексы с 5000 по 8191). Обращение к ptr[8192] приводит к отправке SIGSEGV, на что мы и рассчитывали.

Вторая ситуация: размер области памяти (15000 байт) превышает размер файла (5000 байт):

solaris % rm foo

solaris % test1 foo 5000 15000

ptr[0] = 0

ptr[4095] = 0

ptr[4096] = 0

ptr[8191] = 0

Bus Error(coredump)

solaris % ls –l foo

– rw-r-r– 1 rstevens other1 5000 Mar 20 17:37 foo
 

Рис. 12.9. Размер области памяти больше размера отображаемого файла

Полученный результат аналогичен результату предыдущего примера, в котором размер файла равнялся размеру области отображения (5000 байт). Однако в данном примере генерируется сигнал SIGBUS (о чем интерпретатор оповещает сообщением Bus Error), тогда как в предыдущем примере отправлялся сигнал SIGSEGV. Отличие в том, что SIGBUS означает выход за грaницы отображенного файла внутри области отображения, a SIGSEGV — выход за грaницы области. Этим примером мы показали, что ядро хранит информацию о размере отображенного объекта, даже несмотря на то, что его дескриптор закрыт. Ядро позволяет указать при вызове mmap размер области памяти, больший размера файла, но не позволяет обратиться к адресам в этой области (кроме остатка последней страницы, в которой еще имеется содержимое собственно файла — индексы с 5000 по 8191 в данном случае). На рис. 12.9 приведена иллюстрация к этому примеру. 

Следующая программа приведена в листинге 12.7. Ею мы иллюстрируем типичные методы работы с увеличивающимися в размерах файлами: при отображении в память заказывается большой размер области, текущий размер файла учитывается при всех операциях (чтобы не выйти за его пределы в памяти), а затем он просто увеличивается, по мере того как в файл записываются данные.

Листинг 12.7. Отображение увеличивающегося файла в память

//shm/test2.c

1 #include "unpipc.h"

2 #define FILE "test.data"

3 #define SIZE 32768

4 int

5 main(int argc, char **argv)

6 {

7 int fd, i;

8 char *ptr;

9 /* открытие, создание, урезание и установка размера файла, вызов mmap */

10 fd = Open(FILE, O_RDWR | O_CREAT | O_TRUNC, FILE_MODE);

11 ptr = Mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

12 for (i = 4096; i <= SIZE; i += 4096) {

13 printf("setting file size to %d\n", i);

14 Ftruncate(fd, i);

15 printf("ptr[%d] = %d\n", i-1, ptr[i-1]);

16 }

17 exit(0);

18 }

Открытие файла

9-11 Мы создаем файл, если он еще не существует, или урезаем его до нулевой длины, если он существует. Затем файл отображается в область объемом 32 768 байт, хотя его текущий размер равен нулю.

Увеличение размера файла

12-16 Мы увеличиваем размер файла на 4096 байт за один вызов ftruncate (раздел 13.3) и считываем из него последний байт в каждом проходе цикла.

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

alpha % ls –l test.data

test.data: No such file or directory

alpha % test2

setting file size to 4096

ptr[4095] = 0

setting file size to 8192

ptr[8191] = 0

setting file size to 12288

ptr[12287] = 0

setting file size to 16384

ptr[16383] = 0

setting file size to 20480

ptr[20479] = 0

setting file size to 24576

ptr[24575] = 0

setting file size to 28672

ptr[28671] = 0

setting file size to 32768

ptr[32767] = 0

alpha % ls-l test.data

– rw-r--r-- 1 rstevens other1 32768 Mar 20 17:53 test.data

Этот пример показывает, что ядро всегда следит за размером отображаемого в память объекта (в данном примере это файл test.data), и мы всегда имеем возможность обратиться к байтам, лежащим внутри области, ограниченной размером файла и размером отображения. Те же результаты получаются при запуске этой программы в Solaris 2.6.

  • Читать дальше
  • 1
  • ...
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: