Материал: 6262

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

96

указателя NULL;

free(...) — освобождает память ОЗУ, которая ранее была выделена одной из функций: malloc(...), calloc(...) или realoc(...); если аргумент функции равен NULL, то никаких действий не производится;

calloc(...) - выделяет память ОЗУ под массив данных, размерность которого задана первым аргументом, а размер каждого элемента массива в байтах, задан вторым аргументом; при этом, значение каждого байта выделенной памяти обнуляется; возвращает указатель на выделенный массив данных; если значение любого из аргументов функции равно нулю, то память ОЗУ процессу не выделяется и возвращается значение NULL;

realloc(...) - изменяет размер уже выделенного блока памяти, используя первый аргумент как указатель, а второй — как нужный размер; если размер области уменьшается, то значения байт оставшейся области не изменяется; если размер области увеличивается, то добавляемая область не инициализируетсся; если значение аргумента указателя равно NULL, то результат функции, соответствует действию функции malloc(...); если требование на новый размер памяти равно нулю, а указатель не равен NULL, то действие эквивалентно функции free(...).

На листинге 2.5, приведен пример программы, которая сначала выделяет блоки памяти функциями malloc(...) и calloc(...), а затем освобождает первую из этих областей.

Листинг 2.5 - Пример программы динамического выделения памяти программе

#include <stdio.h> #include <stdlib.h> #include <malloc.h>

void * ptr1 = NULL; void * ptr2 = NULL;

int main(void) {

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

printf("Размеры областей ptr1,ptr2 до выделения ОЗУ:\n"); printf(" ptr1 =%10lu\n", malloc_usable_size(ptr1)); printf(" ptr2 =%10lu\n", malloc_usable_size(ptr2));

printf("Выделяем 100 байт по 1 Кбайт для первой области\n"); if(!(ptr1 = (char*)malloc(100*1024))){

printf("Не могу выделить память..."); exit(EXIT_FAILURE);

}

printf("Размеры ptr1,ptr2 после выделения ОЗУ malloc():\n"); printf(" ptr1 =%10lu\n", malloc_usable_size(ptr1)); printf(" ptr2 =%10lu\n", malloc_usable_size(ptr2));

printf("Выделяем ОЗУ из, 10 элементов массива по 1 Кбайт, для второй области\n");

ptr2 = calloc(10, 1024);

printf("Размеры ptr1,ptr2 после выделения ОЗУ calloc():\n"); printf(" ptr1 =%10lu\n", malloc_usable_size(ptr1)); printf(" ptr2 =%10lu\n", malloc_usable_size(ptr2));

97

printf("Освобождаем 1-ю область ОЗУ:\n"); free(ptr1);

printf("Размеры ptr1,ptr2 после освобождения ОЗУ:\n"); printf(" ptr1 =%10lu\n", malloc_usable_size(ptr1)); printf(" ptr2 =%10lu\n", malloc_usable_size(ptr2));

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

} // Конец листинга 2.5

Задание 2.5

С помощью утилиты man, провести изучение функций: malloc(...), calloc(...), realloc(...) и free(...).

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

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

Кроме перечисленных, имеются также системные функции brk(...) и sbrk(...), с помощью которых можно непосредственно изменять конец сегмента неинициализированных данных.

Синтаксис этих системных вызовов:

#include <unistd.h>

int brk (void *addr); void *sbrk(intptr_t increment);

Семантика системных вызовов:

brk(...) - устанавливает конец сегмента данных в значение, указанное в аргументе addr, когда это значение является приемлимым; указание адреса памяти должно быть в пределах максимально возможного размера сегмента данных (см. setrlimit(2));

sbrk(...) - увеличивает пространство данных программы на increment байт; sbrk(...) не является системным вызовом, он просто является оберткой (wrapper), которую использует библиотека C для вызова brk(...); вызов sbrk(...) с инкрементом 0 может быть использован, чтобы найти текущее местоположение прерывания программы.

Вслучае успеха brk(...) возвращает ноль, а sbrk(...) возвращает указатель на начало новой области. В случае ошибки, возвращается -1 и значение errno устанавливается в значение ENOMEM.

На листинге 2.6 приведен пример программы, которая с помощью функции sbrk(...) три раза изменяет границу сегмента неинициализированных данных.

98

Листинг 2.6 - Пример использования функции sbrk(...)

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

char * ptr = NULL;

int main(void) {

puts("Проект lab8.6 ..."); ptr = sbrk(0);

if (ptr == (char *)-1)

{

perror("Нет доступного пространства для sbrk(...)\n"); exit(EXIT_FAILURE);

}

printf("Первый адрес после добавляемой области: %23lp\n", (char *)ptr);

ptr = sbrk(4096);

if (ptr == (char *)-1)

{

perror("Нет доступного пространства для sbrk(...)\n"); exit(EXIT_FAILURE);

}

printf("Первый адрес после первого добавления 4096 байт: %14lp\n", (char *)ptr);

ptr = sbrk(4096);

if (ptr == (char *)-1)

{

perror("Нет доступного пространства для sbrk(...)\n"); exit(EXIT_FAILURE);

}

printf("Первый адрес после второго добавления 4096 байт: %14lp\n", (char *)ptr);

ptr = sbrk(0);

if (ptr == (char *)-1)

{

perror("Нет доступного пространства для sbrk(...)\n"); exit(EXIT_FAILURE);

}

printf("Первый адрес после добавленной области: %23lp\n", (char *)ptr);

ptr = sbrk(8192); ptr = sbrk(8192);

if (ptr == (char *)-1)

{

perror("Нет доступного пространства для sbrk(...)\n"); exit(EXIT_FAILURE);

}

printf("Первый адрес после двойного добавления по 8192 байт: %10lp\n", (char *)ptr);

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

} // Конец листинга 2.6

99

Задание 2.6

В среде разработки Eclipse, создать проект с именем lab8.6. Набрать текст программы, руководствуясь текстом листинга 2.6. Отладить и провести исследование работы полученной программы.

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

Замечание

При выполнении задания 2.6 необходимо внимательно отслеживать: когда функция sbrk(...) показывает на начало выделенной области, а когда — за конец выделенной области.

Этим заданием, лабораторная работа №8 — заканчивается.

Не забудьте оформить отчет о проделанной работе.

100

3 Тема 9. Базовое взаимодействие процессов

В первой части нашей дисциплины, мы использовали понятие процесса как минимальную программную единицу, управляемую ядром ОС, но при более подробном рассмотрении оказывается, что:

современные ОС, наряду с управлением отдельными процессами, управляют

также потоками (нитями, threads) процессов, обеспечивая им более широкие функциональные возможности;

наряду с разделением времени между процессами, ядро ОС учитывает также

приоритетность процессов;

имеются также разные подходы и к общему стилю управления процессами,

что демонстрируется разными способами организации запуска и контроля работы процессов, которые представлены ПО: init, upstart и systemd.

Замечание

Далее предполагается, что студент уже хорошо усвоил учебный материал «Темы 6» данной дисциплины. Также настоятельно рекомендуется изучить второй раздел учебника [1].

В целом, изучене данной темы предполагают последовательное рассмотрение следующих вопросов:

общие вопросы управления процессами содержат перечень основных качественных характеристик, которые учитываются при разработке подсистемы;

вопрос синхронизация процессов описывает проблематику взаимодействия

активных элементов ПО, необходимые для реализации их прикладных алгоритмов работы;

стандарты POSIX отражают стремление унифицировать средства взаимо-

действия процессов, необходимые для адекватного отражения их в инструментальные средства языка С;

системные вызовы ОС по управлению процессами содержат перечень наиболее важных функций, предоставляемых ядром ОС;

системные вызовы fork() и каналы процессов представляют самый главный инструмент взаимодействия процессов;

потоки (нити, threads) описывают наиболее совершенные средства взаимо-

действия «родственных» процессов, разделяющих общее адресное пространство команд и данных программы;

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

теоретически исполняются одновременно, но реально - активен толко один процесс, а остальные находятся или в состоянии «Готовность» или в состоянии «Ожидание».

Источник: https://studfile.net/preview/16438530/