основы СПО(2).pptx
- Количество слайдов: 28
Системное программное обеспечение Межпроцессное взаимодействие
Процесс • Процесс – выполнение инструкций программы на процессоре. • Стандарт ISO 9000: 2000 Definitions определяет процесс как совокупность взаимосвязанных и взаимодействующих операций, преобразующих входящие данные в исходящие. • Часто процессом называют выполняющуюся программу и все её элементы: адресное пространство, глобальные переменные, регистры, открытые файлы, используемые ресурсы. . . 2
Предпосылки многопроцесности • Декомпозиция исходной задачи и решение каждой подзадачи отдельным процессом • Необходимость параллельного выполнения нескольких программ одновременно • Необходимость построения модульных систем 3
Процессы в виртуальной памяти 4
Управляющий блок процесса Идентификаторы, которые могут храниться в управляющем блоке процесса: • Идентификатор данного процесса • Идентификатор родительского процесса • Идентификатор пользователя 5
Управляющий блок процесса Информация о состоянии процессора: • Регистры, доступные пользователю • Счетчик команд • Регистр флагов 6
Управляющий блок процесса Управляющая информация, используемая для планирования: • Состояние процесса • Приоритет • Информация, необходимая для планирования (время ожидания или выполнения) • Информация о событиях (идентификация события, наступление которого позволит продолжить выполнение процесса) 7
Переключение контекста — прекращение выполнения процессором одной задачи (процесса, потока) с сохранением всей необходимой информации и состояния, необходимых для последующего продолжения с прерванного места, и восстановление состояния задачи, к выполнению которой переходит процессор. Переключение контекста заключается в планировании и смене управляющих блоков процессов. 8
Подходы к планированию • • Round Robin (RR) Shortest-Job-First (SJF) First-Come, First-Served (FCFS) Приоритетное планирование 9
Round Robin 10
Состояния процесса 11
Средства для межпроцессного взаимодействия • • Неименованные каналы Именованные каналы Сигналы Разделяемая память Сокеты RPC (RMI) Очереди сообщений 12
Взаимодействие через канал Передача данных по принципу FIFO 13
Взаимодействие через канал #include <stdio. h> #include <string. h> #include <sys/types. h> #define BUF_SIZE 1024 void main (int argc, char * argv[]) { int fd[2]; pipe(fd); int pid = fork(); if (pid>0) { char symb[] = "Hello!n"; int length=sizeof(symb); close(fd[STDIN_FILENO]); write(fd[STDOUT_FILENO], symb, length + 1); close(fd[STDOUT_FILENO]); } else { char buf[BUF_SIZE]; int len; close(fd[STDOUT_FILENO]); while ((len = read(fd[0], buf, BUF_SIZE)) != 0) write(STDOUT_FILENO, buf, len); close(fd[STDIN_FILENO]); } exit(0); } 14
pipe() #include <unistd. h> int pipe(int pipefd[2]); Функции pipe() передается единственный параметр - массив типа int, состоящий из двух элементов. В первом элементе массива функция возвращает дескриптор файла, служащий для чтения данных из канала, а во втором - дескриптор для записи. 15
fork() #include <sys/types. h> #include <unistd. h> pid_t fork(void); fork создает процесс-потомок, который отличается от родительского только значениями PID (идентификатор процесса) и PPID (идентификатор родительского процесса), а также тем фактом, что счетчики использования ресурсов установлены в 0. При успешном завершении родителю возвращается PID процессапотомка, а процессу-потомку возвращается 0. При неудаче родительскому процессу возвращается -1, процесс-потомок не создается, а значение ERRNO устанавливается должным образом. 16
Канал между двумя процессами родительский процесс дочерний процесс fd[0] fd[1] процесс ядро канал поток данных 17
Канал после вызова fork родительский процесс дочерний процесс fork fd[0] fd[1] процесс ядро канал поток данных 18
Конвейер из трех процессов who процесс sort процесс nl процесс stdout stdin процесс ядро канал 1 канал 2 поток данных 19
Двусторонняя передача данных по двум каналам родительский процесс дочерний процесс fd[1] fd[0] процесс ядро канал 1 поток данных канал 2 поток данных 20
Использование неименованного канала #include <stdio. h> #include <errno. h> #include <unistd. h> #define BUF_SIZE 128 void main(int argc, char * argv[]) { FILE * open_from_proc; int len; char buf[BUF_SIZE]; open_from_proc = popen(argv[1], "r"); if (open_from_proc == NULL) { perror("Error while popen: n"); exit(-1); } while ((len = read(buf, BUF_SIZE, open_from_proc)) != 0) { write(STDOUT_FILENO, buf, len); } pclose(open_from_proc); exit(0); } 21
popen() и pclose() #include <stdio. h> FILE *popen(const char* command, const char* mode); Функция popen() запускает внешнюю программу и возвращает вызвавшему ее приложению указатель на структуру FILE, связанный либо со стандартным потоком ввода, либо со стандартным потоком вывода запущенного процесса. Первый параметр - строка, содержащая команду, запускающую внешнюю программу. Второй параметр определяет, какой из стандартных потоков (вывода или ввода) будет возвращен. “w” соответствует потоку ввода запускаемой программы, “r” - потоку вывода. Особенность функции popen() заключается в том, что эта функция не возвращает NULL, даже если переданная ей команда не является корректной. Самый простой способ обнаружить ошибку в этой ситуации - попытаться прочесть данные из потока вывода. Если в потоке вывода нет данных (read возвращает значение 0), значит произошла ошибка. Функция pclose() используется для закрытия канала. 22
Именованные каналы родительский процесс дочерний процесс writefd readfd процесс ядро /tmp/fifo. 1 поток данных /tmp/fifo. 2 поток данных 23
Использование именованного канала. Приложение 1 #include <stdio. h> #include <sys/types. h> #include <sys/stat. h> #define fifo ". /fifo" void main(int argc, char * argv[]) { mkfifo(fifo, 0700); FILE * file_fifo = fopen(fifo, "w"); char ch; do { ch = getchar(); fputc(ch, file_fifo); if (ch == 10) fflush(file_fifo); } while (ch != 'q'); fclose(file_fifo); unlink(fifo); exit(0); } 24
Использование именованного канала. Приложение 2 #include <stdio. h> #define fifo ". /fifo" void main () { FILE * file_fifo; char ch; file_fifo = fopen(fifo, "r"); do { ch = fgetc(file_fifo); putchar(ch); } while (ch != 'q'); fclose(file_fifo); unlink(fifo); exit(0); } 25
mkfifo() #include <stdio. h> FILE *mkfifo(const char* pathname, mode_t mode); Функция mkfifo создает особый FIFO-файл с названием pathname. mode определяет права доступа. Как только таким образом создан особый FIFO-файл, любой процесс может открыть его для чтения или записи так же, как и любой обычный файл. Перед тем как проводить операции ввода/вывода, файл FIFO необходимо открыть как на чтение, так и на запись. 26
fflush() #include <stdio. h> int fflush(FILE *stream); Функция fflush() принудительно записывает все буферизированные данные в устройство вывода данных или корректирует поток stream посредством определенных для него функций записи. 27
unlink() #include <stdio. h> int unlink(const char *pathname); unlink удаляет имя из файловой системы. Если это имя было последней ссылкой на файл и больше нет процессов, которые держат этот файл открытым, данный файл удаляется и место, которое он занимает освобождается для дальнейшего использования. Если имя было последней ссылкой на файл, но какие-либо процессы всё ещё держат этот файл открытым, файл будет оставлен пока последний файловый дескриптор, указывающий на него, не будет закрыт. Если имя указывает на символьную ссылку, ссылка будет удалена. Если имя указывает на сокет, FIFO или устройство, имя будет удалено, но процессы, которые открыли любой из этих объектов могут продолжать его использовать. 28
основы СПО(2).pptx