Реализация взаимодействия процессов. Взаимодействие процессов взаимодействие в рамках локальной ЭВМ (одной ОС) взаимодействие в рамках сети родственные.

Презентация:



Advertisements
Похожие презентации
Реализация взаимодействия процессов. Взаимодействие процессов взаимодействие в рамках локальной ЭВМ (одной ОС) взаимодействие в рамках сети родственные.
Advertisements

Реализация взаимодействия процессов. Взаимодействие процессов взаимодействие в рамках локальной ЭВМ (одной ОС) взаимодействие в рамках сети родственные.
Управление процессами. Определение процесса. Основные понятия Процесс совокупность машинных команд и данных, которая исполняется в рамках вычислительной.
Управление процессами. Определение процесса. Основные понятия Процесс совокупность машинных команд и данных, которая обрабатывается в рамках вычислительной.
Система межпроцессного взаимодействия IPC. Общие концепции #include key_t ftok ( char * filename, char proj ) filename строка, cодержащая имя файла proj.
2.Система межпроцессного взаимодействия IPC 2.1.Состав, общие концепции 2.2.Очередь сообщений 2.3.Разделяемая память 2.4.Массив семафоров Взаимодействие.
Система межпроцессного взаимодействия IPC.. Система межпроцессного взаимодействия IPC. Состав. Очереди сообщений Семафоры Разделяемая память.
3. Механизм сокетов 3.1. Общие концепции 3.2. Интерфейсные функции для работы с сокетом Создание сокета Связывание и установление соединения.
Взаимодействие процессов: сокеты.
Процессы и потоки. Процессы В общем представлении, процесс - это программа, выполняющаяся в оперативной памяти компьютера. Реально, все гораздо сложней.
СОКЕТЫ. СОКЕТ Сокет – программный интерфейс для обеспечения обмена данными между процессами. Впервые socket API появилась в BSD Unix. Описан в POSIX В.
СИСТЕМНЫЕ ВЫЗОВЫ ВВОДА И ВЫВОДА Системные вызовы и библиотеки Unix SVR4.
Система межпроцессного взаимодействия IPC.. Система межпроцессного взаимодействия IPC. Состав. Очереди сообщений Семафоры Разделяемая память.
1 Архитектура вычислительных систем. Лекция 8. Ловецкий К.П. Москва, декабрь 2012 Управление свойствами процесса.
Механизм сокетов Средства межпроцессного взаимодействия ОС Unix, представленные в системе IPС, решают проблему взаимодействия процессов, выполняющихся.
Инструкции C++ Условная инструкция Формат: if (условие) оператор; else оператор; Пример: if (i!=0) { if (j) j++; if(k) k++; else if(p) k--; } else i--;
Многопоточное программирование. Виды параллелизма. Общая память Распределенная память.
1 Операционные системы и оболочки Одинцов Игорь Олегович ст. преподаватель кафедры информатики весна 2006.
Параллельное программирование с использованием технологии MPI Аксёнов Сергей Владимирович к.т.н., доцент каф.ОСУ ТПУ Лекция 4 Томский политехнический университет.
Работа с файлами FILE НГТУ ИРИТ кафедра ИСУ Ольга Пронина.
Транксрипт:

Реализация взаимодействия процессов

Взаимодействие процессов взаимодействие в рамках локальной ЭВМ (одной ОС) взаимодействие в рамках сети родственные процессы произвольные процессы неименованные каналы трассировка именованные каналы сигналы IPC сокеты MPI

Сигнал – средство уведомления процесса о наступлении некоторого события в системе. Инициаторы посылки сигнала - другой процесс или ОС. Сигналы – механизм асинхронного взаимодействия, момент прихода сигнала процессу заранее неизвестен. Сигналы

Обработка сигнала работа процесса приход сигнала Обработка сигнала по умолчанию Вызов функции- обработчика Игнорирование сигнала Примеры сигналов SIGINT (2) SIGQUIT (3) SIGKILL (9) SIGALRM (14) SIGCHLD (18)

#include int kill (pit_t pid, int sig); Работа с сигналами pid –идентификатор процесса, которому посылается сигнал sig – номер посылаемого сигнала При удачном выполнении возвращает 0, в противном случае возвращает -1

Работа с сигналами #include void (*signal ( int sig, void (*disp) (int))) (int) sig –номер сигнала, для которого устанавливается реакция disp – либо определенная пользователем функция – обработчик сигнала, либо одна из констант: SIG_DFL – обработка по умолчанию SIG_IGN - игнорирование При успешном завершении функция возвращает указатель на предыдущий обработчик данного сигнала.

#include int count=1; Пример. Обработка сигнала. void SigHndlr (int s) {printf("\n I got SIGINT %d time(s) \n", count ++); if (count==5) signal (SIGINT, SIG_DFL); else signal (SIGINT, SigHndlr); } int main(int argc, char **argv) {signal (SIGINT, SigHndlr); while (1);/*тело программы*/ return 0; }

#include const char * tempfile = abc; Пример. Удаление временных файлов при завершении программы. void SigHndlr (int s) { unlink(tempfile); } int main(int argc, char **argv) { signal(SIGINT, SigHndlr); … creat(tempfile, 0666); … unlink(tempfile); return 0; }

Пример. Программа будильник. int main(int argc, char **argv) { char s[80]; signal(SIGALRM, alrm); alarm(5); printf(Введите имя \n); for (;;) { printf(имя:); if (gets(s) != NULL) break; }; printf(OK! \n); return 0; } void alrm (int s) { printf(\n жду имя \n); alarm(5); signal (SIGALRM,alrm); } #include

Пример. Двухпроцессный вариант программыбудильник. #include void alr(int s) { printf(\n Быстрее!!! \n); signal (SIGALRM, alr); } int main(int argc, char **argv) { char s[80]; int pid; signal(SIGALRM, alr); if (pid=fork()) {/*отец*/} else {/*сын*/} return 0; }

Пример. Двухпроцессный вариант программыбудильник. /*отец*/ for (;;) { sleep(5); kill(pid, SIGALRM); } /*сын*/ printf(Введите имя \n); for (;;) { printf(имя:); if (gets(s) != NULL) break; } printf(OK!\n); kill(getppid(), SIGKILL);

Неименованные каналы.

Неименованные каналы. Отличительные свойства. Невозможен доступ по имени (доступ только по файловым дескрипторам) Канал не существует вне процесса Реализуется модель последовательного дотупа к данным (FIFO)

#include int pipe (int *fd); Неименованные каналы. Системный вызов pipe( ) fd – возвращаемый вызовом массив файловых дескрипторов fd[1] – для записи в канал fd[0] – для чтения из канала

Особенности организации чтения из канала. Если прочитано меньше байтов, чем находится в канале, оставшиеся сохраняются в канале Если - попытка чтения из канала - данных недостаточно - существуют открытые дескрипторы записи то имеющиеся данные изымаются, канал блокируется, пока не появятся остальные Можно избежать блокировки, используя вызов fcntl() При закрытии записывающей стороны канала в него помещается EOF (при считывании не будет блокирования)

Особенности организации записи в канал. Если процесс пытается записать больше байтов, чем помещается в канал, то возможное количество данных записывается, процесс блокируется, пока не будет достаточно места Можно избежать блокировки, используя вызов fcntl() Если процесс пытается записать в канал, с которым не ассоциирован ни один дескриптор чтения, то он получает сигнал SIGPIPE

Пример. Использование канала. int main(int argc, char **argv) { char s*=chanel; char buf[80]; int pipes[2]; pipe(pipes); write(pipes[1],s,strlen(s)+1); read(pipes[0],buf,strlen(s)+1); close(pipes[0]); close(pipes[1]); printf(%s\n,buf); }

Пример. Схема взаимодействия процессов с использованием канала. int main(int argc, char **argv) { int fd[2]; pipe(fd); if(fork()) {close(fd[0]); write (fd[1], …); … close(fd[1]); … } else {close(fd[1]); while(read(fd[0],…)){…} … }

Пример. Реализация конвейера. #include int main(int argc, char **argv) { int fd[2]; pipe(fd); if(fork()) { dup2(fd[1],1); close(fd[1]); close(fd[0]); exelp(print,print,0); } dup2(fd[0],0); close(fd[0]); close(fd[1]); execl(/usr/bin/wc,wc,0); }

#include #define MAX_CNT 100 int target_pid, cnt; int fd[2]; int status; Пример. Совместное использование сигналов и каналов – «пинг-понг».

void SigHndlr (int s) { signal(SIGUSR1, SigHndlr); if (cnt < MAX_CNT) { read(fd[0], &cnt, sizeof(int)); printf("%d \n", cnt); cnt++; write(fd[1], cnt, sizeof(int)); kill(target_pid, SIGUSR1); } …

Пример. Совместное использование сигналов и каналов – «пинг-понг». … else if (target_pid == getppid()) { printf("Child is going tobe terminated\n"); close(fd[1]); close(fd[0]); exit(0); } else kill(target_pid, SIGUSR1); }

Пример. Совместное использование сигналов и каналов – «пинг-понг». int main(int argc, char **argv) { pipe(fd); signal(SIGUSR1, SigHndlr); cnt = 0; if (target_pid = fork()) { wait(&status); printf("Parent is going to be terminated\n"); close(fd[1]); close(fd[0]); return 0; …

Пример. Совместное использование сигналов и каналов – «пинг-понг». … } else { target_pid = getppid(); write(fd[1], &cnt, sizeof(int)); kill(target_pid, SIGUSR1); for(;;); }

Именованные каналы.

int mkfifo (char *pathname, mode_t mode); Именованные каналы. Создание. pathname– имя создаваемого канала mode – права доступа владельца/ группы/прочих

Блокировка при подключении; Использование флага O_NONBLOCK или O_NDELAY; Правила работы с именованными каналами полностью аналогичны неименованным каналам. Именованные каналы. Использование системного вызова open().

Пример. «Клиент-сервер». Процесс-сервер: #include

Пример. «Клиент-сервер». Процесс-сервер: int main(int argc, char **argv) { int fd; int pid; mkfifo("fifo", S_IFIFO | 0666); fd = open ("fifo", O_RDONLY | O_NONBLOCK); while ( read (fd, &pid, sizeof(int) ) == -1); printf ("Server %d got message from %d !\n", getpid(), pid); close (fd); unlink ("fifo"); }

Пример. «Клиент-сервер». Процесс-сервер: int main(int argc, char **argv) { int fd; int pid = getpid( ); fd = open ("fifo", O_RDWR); write (fd, &pid, sizeof(int)); close (fd); } #include

Межпроцессное взаимодействие, проводимое по модели «главный-подчинённый».

Модель подчиненный-главный Трассировка – возможна между родственными процессами: Процесс-родитель может вести трассировку только непосредственно порожденных им потомков, при этом процесс-потомок должен дать разрешение на это.

Системный вызов ptrace() #include int ptrace(int cmd, int pid, int addr, int data); cmd – код выполняемой команды pid – идентификатор процесса-потомка addr – некоторый адрес в адресном пространстве процесса-потомка data – слово информации.

Системный вызов ptrace() #include int ptrace(int cmd, int pid, int addr, int data); cmd=PTRACE_TRACEME вызывает сыновний процесс, позволяя трассировать себя cmd=PTRACE_PEEKDATA чтение слова из адресного пространства отлаживаемого процесса cmd=PTRACE_PEEKUSER чтение слова из контекста процесса (из пользовательской составляющей, содержащейся в ) cmd=PTRACE_POKEDATA запись данных в адресное пространство процесса-потомка cmd=PTRACE_POKEUSER запись данных в контекст трассируесого процесса.

Системный вызов ptrace() #include int ptrace(int cmd, int pid, int addr, int data); cmd=PTRACE_GETREGS,PTRACE_GETFREGS чтение регистров общего назначения cmd=PTRACE_SETREGS,PTRACE_SETFREGS запись в регистры общего назначения cmd=PTRACE_CONT возобновление выполнения трассируемого процесса cmd=PTRACE_SYSCALL, PTRACE_SINGLESTEP возобновляется выполнение трассируемой программы, но снова останавливается после выполнения одной инструкции cmd=PTRACE_KILL завершение выполнения трассируемого процесса

Общая схема трассировки процессов Процесс-потомок ptrace(PTRACE_TRACEME, 0, 0, 0); exec(…);... Процесс-предок wait(…); for(;;) { … ptrace(PTRACE_SINGLESTEP, …); … wait(…); … } cигнал SIGTRAP cигнал SIGTRAP

Пример. int main(int argc, char **argv) { return argc/0; } #include

Пример. int main(int argc, char *argv[]) { pid_t pid; int status; struct user_regs_struct REG; if ((pid = fork()) == 0) { ptrace(PTRACE_TRACEME, 0, 0, 0); execl(son, son, 0); } …

while (1) { wait( &status ); ptrace(PTRACE_GETREGS, pid, &REG, &REG); printf("signal = %d, status = %#x, EIP=%#x, ESP=%#x\n, WSTOPSIG(status), status, REG.eip, REG.esp); if (WSTOPSIG(status) != SIGTRAP) { if (!WIFEXITED(status)) ptrace (PTRACE_KILL, pid, 0, 0); break; } ptrace (PTRACE_CONT, pid, 0, 0); } Пример.