Skip to content

Home Программирование Концепция "черных дыр"
Концепция "черных дыр"

Начнем сразу с эксперимента. Для этого создадим программу, которая необычным образом использует системный вызов lseek().

Программа biackhole.с

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#define HOLE_SI2E 5
int main (void) {
int fd = creat ("myfile", 0640); if (fd == -1) {
fprintf (stderr, "Cannot open file\n"); return 1; }
write (fd, "AAA", 3);
if (lseek (fd, HOLE_SIZE, SEEK_END) == -1) {
fprintf (stderr, "Cannot set I/O position\n");
return 1; }
write (fd, "BBB", 3); close (fd); return 0; }

Эта программа записывает в файл myfile три байта информации, затем выводит текущую позицию ввода-вывода за границы файла, после чего записывает еще три байта. В результате получился файл длиной в 11 байт:

$ Is -1 myfile
-rw-r---- i nn users 11 2006-12-15 02:54 myfile

Возникает вопрос: что же содержится в промежутке между первой и второй триадами записанных байтов? В этом случае каждый текстовый редактор будет отображать данный промежуток по-своему. Например, текстовый процессор OpenOffice.org Writer, в котором, кстати, написана эта книга, выстроил цепочку из пяти решеток (#). Но если воспользоваться программой cat, то никаких промежуточных символов мы не обнаружим:

$ cat myfile АААВВВ

Выход только один — написать еще одну программу, которая выведет ASCII-код каждого символа, содержащегося в myfile.

Программа showhole.с

#include <fcntl.h> 
#include <unistd.h>
#include <stdio.h>
int main (int argc, char ** argv) {
int fd;
char ch;
if (argc < 2) {
fprintf (stderr, "Too few arguments\n");
return 1; }
fd = open ( argv[1], 0_RDONLY);
if (fd == -1) {fprintf (stderr, "Cannot open file\n");
return 1; }
while (read (fd, &ch, 1) > 0)
. printf ("code: %d\n", ch) ;
close (fd); return 0; }


Оказалось, что наш файл содержит в промежутке нулевые байты:

S  ./showhole myfile
code: 65
code: 65
code: 65
code: 0
code: 0
code: 0
code: 0
code: 0
code: 66
code: 66
code: 66

На первый взгляд— ничего особенного. Но давайте попробуем увеличить нашу "черную дыру" до 20 Мбайт. Для этого изменим значение константы hole_size в файле blackhole.c:

#define HOLE_SIZE (1024*1024*20)

Не торопитесь запускать полученную программу. Давайте сначала удалим прежний файл myfile и проверим, сколько мегабайт памяти занято в файловой системе:

$ rm myfile
$ df -mТ .Filesystem Type lM-blocks Used Available Use% Mounted on
/dev/hda5 ext3 23723 14067 8432 63% /home

Утилита df служит для просмотра информации об использовании файловой системы и дисков.

Теперь запустим программу и проверим, что получилось:

$ ./blackhole $ Is -lh myfile
-rw-r---- 1 nn users 21M 2006-12-15 03:30 myfile
$ df -mT .
Filesystem Type lM-blocks Used Available Use% Mounted on
/dev/hda5 ext3 23723 14067 8432 63% /home

Итак, несмотря на то, что в файловой системе появился файл размером более 20 Мбайт, это никак не отразилось на статистике использования дискового пространства.

В приведенном примере опция -т программы df была указана не просто так. Оказывается, "продвинутые" файловые системы, наподобие ext3, реагируют на "черные дыры" в файлах особенным образом: нули, которыми заполнена "черная дыра", на самом деле не записываются в файл. Каждый раз, когда программа посредством системного вызова read() обращается к ядру с запросом на чтение данных из "пустого" промежутка, файловая система просто генерирует нулевые байты.

Флаг -т заставляет утилиту df выводить тип файловой системы.

Следует помнить, что такое поведение характерно не для всех типов файловых систем. Если, например, поместить файл myfile в файловую систему ОС Windows, то диск реально заполнится 20-ю мегабайтами нулей.

Комментарии (0)

RSS feed Comments

Написать комментарий

smaller | bigger

busy
 

Регистрация




Top