Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
6262.pdf
Скачиваний:
37
Добавлен:
13.02.2021
Размер:
6.54 Mб
Скачать

91

2.5.3 Создание и удаление процессов из памяти

Структура процессов ОС Linux следует современным тенденциям построения операционных систем, в плане использования ими основной памяти ЭВМ:

они полностью используют виртуальную адресацию памяти;

ядро ОС фиксирует основные характеристики всех запущенных процессов.

Внастоящее время, ядро ОС использует 32-битную виртуальную адресацию пространства процесса, которая составляет размер в 4 ГБ, как показано на рисунке 2.17:

первые 3 ГБ соответствуют пространству пользователя (User space);

последний 1 ГБ находится в распоряжении ядра ОС (Kernel space).

Рисунок 2.17 — Виртуальная адресация процесса ОС Linux

В ядре ОС, для каждого процесса отведена директория страниц, что подразумевает возможность доступа к 1КВ таблицам страниц, которые указывают на 1МВ 4- х килобайтных страниц. Это позволяет адресовать 4 ГБ памяти.

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

92

Замечание

В пользовательском пространстве, линейные адреса и логические адреса - идентичны.

Процесс получает свои таблицы страниц от родителя, при выполнении последним системного вызова fork(), со входами, помеченными как READ-ONLY или замещаемые.

Если процесс пытается писать в некоторую область памяти и страница является COPY-ON-WRITE страницей, то она копируется и помечается как READ-WRITE.

В любом случае, «Cистема управления памятью» Linux осуществляет подкачку страниц по обращению, в соответствии со стратегией COPY-ON-WRITE, которая основана на механизме подкачки и поддерживается процессором i386.

Современные ядра ОС Linux псевдоустройство proc, с файловой системой типа proc, которая монтируется к директории /proc корневой ФС.

Эта файловая система содержит много информации о каждом запущенном процес-

се:директория /proc/<номер процесса> - содержит файлы (псевдофайлы) о разных характеристиках процесса с конкретным номером PID;

директория /proc/self — является уникальной ссылкой для процесса, который обращается к информации о себе и который, как любой дочерний процесс, не знает свой PID.

Вкачестве демострации указанных возможностей, рассмотрим строку данных файла /proc/self/statm, содержащую семь цифровых слов, семантика которых представлена в таблице 2.1.

Таблица 2.1 — Семантика слов файла /proc/<pid>/statm

Номер слова Семантика слова

1 Общий размер программы

2 Размер резидентной части памяти

3 Число разделяемых страниц

4 Число страниц 'code'

5 Число страниц data/stack

6 Число страниц library

7 Число страниц dirty («грязных»)

Замечание

Все строки псевдофайлов заканчиваются символом перевода строки (0x0A).

Другой пример, файл /proc/self/maps, который содержит адреса и другие параметры всех ресурсов, привязанных к текущему процессу.

93

На листинге 2.3, представлен текст программы, которая читает и выводит на терминал информацию из файлов /proc/self/statm и /proc/self/maps.

Листинг 2.3 - Пример вывода файлов /proc/self/stats и /proc/self/maps

#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h>

int main(void) {

puts("Проект lab8.3 ...");

 

 

char

 

 

buf[BUFSIZ];

 

 

 

 

 

 

int i, j, fd;

 

 

ssize_t n;

 

 

char *pw[7];

 

 

fd = open("/proc/self/statm", O_RDONLY);

 

if(fd < 0){

 

 

 

 

perror("open /proc/self/statm");

 

}

 

exit(EXIT_FAILURE);

 

 

 

 

 

 

 

 

 

 

 

puts("Содержимое файла /proc/self/statm:");

 

n = read(fd,

buf, BUFSIZ);

 

 

if(fd < 0){

 

 

 

 

 

 

perror("read /proc/self/statm:");

 

}

 

exit(EXIT_FAILURE);

 

 

 

 

 

 

 

 

 

 

 

close(fd);

 

 

buf[n - 1] = 0;

 

 

puts

(buf);

 

 

i = 0;

 

 

j = 0;

 

 

pw[0] =

buf;

 

 

while

(buf[i] != 0) {

 

 

 

 

if

(buf[i] == 0x20) {

// Прочитали слово

 

 

 

 

 

 

buf[i] = 0;

 

 

}

 

 

pw[++j]=

&buf[i + 1];

 

 

 

 

 

 

 

 

}

 

i++;

 

 

 

 

 

 

 

 

 

 

 

printf("%10s - Общий размер программы (в страницах)\n",

pw[0]);

printf("%10s - Размер резидентной части памяти\n",

pw[1]);

printf("%10s - Число разделяемых страниц\n",

pw[2]);

printf("%10s - Число страниц 'code'\n",

pw[3]);

printf("%10s - Число страниц data/stack\n",

pw[4]);

printf("%10s - Число страниц library\n",

pw[5]);

printf("%10s - Число страниц

dirty («грязных»)\n",

pw[6]);

puts("\nСодержимое файла /proc/self/maps:"); read_maps("/proc/self/maps", buf);

puts("Завершение проекта lab8.3 ..."); return EXIT_SUCCESS;

}

int read_maps(const char *fn, char *buf){ int fd;

ssize_t n;

fd = open(fn, O_RDONLY);

94

if(fd < 0){ perror(fn);

return EXIT_FAILURE;

}

while ((n = read(fd, buf, BUFSIZ - 1)) > 0){ buf[n] = 0;

puts(buf);

}

close(fd);

return EXIT_SUCCESS;

}

Задание 2.3

В среде разработки Eclipse, необходимо создать проект с именем lab8.3, руководствуясь текстом листинга 2.3.

Отладить и провести исследование работы полученной программы. Отразить краткое описание работы данного примера в личном отчете.

На листинге 2.4, представлен второй вариант программы, которая читает и выводит на терминал информацию из файлов /proc/self/statm и /proc/self/maps.

В этом примере, программа, относительно себя, выводит только содержимое файла /proc/self/statm, а затем создает дочерний процесс для вызова программы проекта lab8.3.

Листинг 2.4 — Второй пример вывода файлов /proc/self/stats и /proc/self/maps

#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h>

int main(void) {

puts("Проект lab8.4 ...");

char buf[BUFSIZ]; int i, j, fd; ssize_t n;

char *pw[7];

fd = open("/proc/self/statm", O_RDONLY); if(fd < 0){

perror("open /proc/self/statm"); exit(EXIT_FAILURE);

}

puts("Содержимое файла /proc/self/statm:"); n = read(fd, buf, BUFSIZ);

if(fd < 0){

perror("read /proc/self/statm:"); exit(EXIT_FAILURE);

}

close(fd); buf[n - 1] = 0; puts(buf);

i = 0; j = 0;

pw[0] = buf;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]