Скачать презентацию
Идет загрузка презентации. Пожалуйста, подождите
Презентация была опубликована 11 лет назад пользователемНина Ворохобина
1 Система межпроцессного взаимодействия IPC.
2 Система межпроцессного взаимодействия IPC. Состав. Очереди сообщений Семафоры Разделяемая память
3 Общие концепции Для именования объекта IPC используется уникальный ключ, по которому процессу возвращается дескриптор объекта Для каждого IPC-ресурса поддерживается идентификатор его владельца и структура, описывающая права доступа к нему (только две категории прав доступа- по чтению и по записи). информацию о создателе и владельце ресурса, их группе его ключ. struct ipc_perm
4 Общие концепции #include key_t ftok (char *filename, char proj) filename – строка, cодержащая имя файла proj – добавочный символ (может использоваться, например, для поддержания разных версий программы)
5 Общие концепции get(key,....., flags) - создание/подключение Флаги cоздания/подключения: IPC_PRIVATE (доступность только породившему процессу) IPC_CREAT (создать новый или подключиться к существующему) IPC_EXCL ( + IPC_CREAT создание только нового) Значения переменной errno при ошибках: ENOENT (ресурса нет и не указан флаг IPC_CREAT) EEXIST (ресурс существует и флаги IPC_EXCL | IPC_CREAT) EACCESS (нет прав на подключение) ……..
6 IPC: очередь сообщений.
7 Очередь сообщений Организация очереди сообщений по принципу FIFO Использование типов сообщений BAABABA
8 Создание/доступ к очереди сообщений key – ключ msgflag – флаги, управляющие поведением вызова В случае успеха возвращается положительный дескриптор очереди, в случае неудачи возвращается –1. #include #include #include int msgget (key_t key, int msgflag)
9 int msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg) Отправка сообщений msqid– идентификатор очереди, полученный в результате вызова msgget() msgp – указатель на буфер следующей структуры: long msgtype -тип сообщения char msgtext[ ] -данные (тело сообщения) #include
10 int msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg) Отправка сообщений msgsz–размер тела сообщения msgflg 0 процесс блокируется, если для посылки сообщения недостаточно системных ресурсов IPC_NOWAIT – работа без блокировки (возврат –1) #include
11 int msgrcv (int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg) Получение сообщений msqid– идентификатор очереди msgp – указатель на буфер msgsz– размер тела сообщения msgtyp тип сообщения, которое процесс желает получить = 0 любого типа > 0 типа msgtyp < 0 наименьшее значение среди типов, которые меньше модуля msgtyp #include
12 int msgrcv (int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg) Получение сообщений msgflg– побитовое сложение флагов IPC_NOWAIT – если сообщения в очереди нет, то возврат –1 MSG_NOERROR – разрешение получать сообщение, даже если его длина превышает емкость буфера #include В случае успеха возвращает количество прочитанных байтов в теле сообщения
13 int msgctl (int msqid, int cmd, struct msgid_ds *buf) Управление очередью сообщений msgid– идентификатор ресурса cmd– команда IPC_STAT – скопировать структуру, описывающую управляющие параметры очереди по адресу, указанному в параметре buf IPC_SET – заменить структуру, описывающую управляющие параметры очереди, на структуру, находящуюся по адресу, указанному в параметре buf IPC_RMID – удалить очередь. #include
14 int msgctl (int msqid, int cmd, struct msgid_ds *buf) Управление очередью сообщений buf– структура, описывающая параметры очереди. Тип msgid_ds описан в заголовочном файл, и представляет собой структуру, в полях которой хранятся права доступа к очереди, статистика обращений к очереди, ее размер и т.п. #include В случае успеха возвращается 0
15 Пример. Использование очереди сообщений.
16 Основной процесс int main(int argc, chr **argv) { key_t key; int msgid; char str[256]; key = ftok("/usr/mash", 's'); msgid = msgget(key, 0666 | IPC_CREAT | IPC_EXCL); for(;;) { gets(str); strcpy(Message.Data, str);... #include struct { long mtype; char Data[256]; } Message;
17 ... switch (str[0]) { case 'a': case 'A': Message.mtype=1; msgsnd(msgid, (struct msgbuf*) (&Message), strlen(str)+1, 0); break; case 'b: case 'B': Message.mtype=2; msgsnd(msgid, (struct msgbuf*) (&Message), strlen(str)+1, 0); break; case 'q': case 'Q': Message.mtype=1; msgsnd(msgid,(struct msgbuf*) (&Message), strlen(str)+1, 0); Message.mtype=2; msgsnd(msgid,(struct msgbuf*) (&Message), strlen(str)+1, 0); sleep(10); msgctl(msgid, IPC_RMID, NULL); exit(0); default: break; }}}
18 int main(int argc, chr **argv) { key_t key; int msgid; key = ftok("/usr/mash", 's'); msgid = msgget(key, 0666) for(;;) { msgrcv(msgid, (struct msgbuf*) (&Message), 256, 1, 0); printf("%s",Message.Data); if (Message.Data[0]=='q' || Message.Data[0]=='Q') break; }exit();} #include struct { long mtype; char Data[256]; } Message; Процесс-приемник А
19 Пример. Очередь сообщений. Модель «клиент-сервер».
20 Server int main(int argc, chr **argv) { struct { long mestype; char mes [100]; } messageto; struct { long mestype; long mes; } messagefrom; key_t key; int mesid;... #include
21 Server … key = ftok("example", 'r'); mesid = msgget (key, 0666 | IPC_CREAT | IPC_EXCL ); while(1) { msgrcv(mesid, &messagefrom, sizeof(messagefrom)- sizeof(long), 1, 0) messageto.mestype = messagefrom.mes; strcpy( messageto.mes, "Message for client"); msgsnd (mesid, &messageto, sizeof(messageto)- sizeof(long),0); }
22 Client int main(int argc, chr **argv) { struct { long mestype; long mes; } messageto; struct { long mestype; char mes[100]; } messagefrom; key_t key; int mesid;... #include
23 Client... long pid = getpid(); key = ftok("example", 'r'); mesid = msgget (key, 0666); messageto.mestype = 1; messageto.mes = pid; msgsnd (mesid, &messageto, sizeof(messageto)-sizeof(long),0); msgrcv(mesid,&messagefrom, sizeof(messagefrom)-sizeof(long),pid,0); printf("%s",messagefrom.mes); return 0; }
24 IPC: разделяемая память.
25 #include int shmget (key_t key, int size, int shmflg) Создание общей памяти key – ключ для доступа к разделяемой памяти size – размер области памяти shmflg – флаги управляющие поведением вызова В случае успешного завершения вызов возвращает положительное число – дескриптор области памяти, в случае неудачи - -1.
26 #include char *shmat(int shmid, char *shmaddr, int shmflg) Доступ к разделяемой памяти shmid – дескриптор области памяти shmaddr – виртуальный адрес в адресном пространстве, начиная с которого необходимо подсоединить разделяемую память (чаще всего =0, то есть выбор предоставляется системе) shmflg – флаги, например, SHM_RDONLY подсоединяемая область будет использоваться только для чтения. Возвращает адрес, начиная с которого будет отображаться присоединяемая разделяемая память. При неудаче - -1.
27 #include int shmdt(char *shmaddr) Открепление разделяемой памяти shmaddr -адрес прикрепленной к процессу памяти, который был получен при вызове shmat() В случае успешного выполнения функция возвращает 0, в случае неудачи -1
28 #include int shmctl(int shmid, int cmd, struct shmid_ds *buf) Управление разделяемой памятью shmid – дескриптор области памяти cmd – IPC_STAT – скопировать структуру, описывающую управляющие параметры области памяти IPC_SET – заменить структуру, описывающую управляющие параметры области памяти, на структуру, находящуюся по адресу, указанному в параметре buf. IPC_RMID удалить SHM_LOCK, SHM_UNLOCK – блокировать или разблокировать область памяти. buf – структура, описывающая управляющие параметры области памяти.
29 int main(int argc, chr **argv) { key_t key; char *shmaddr; key = ftok(/tmp/ter, S); shmid=shmget(key, 100, 0666 | IPC_CREAT | IPC_EXCL); shmaddr = shmat(shmid, NULL, 0); putm(shmaddr); waitprocess(); shmctl(shmid, IPC_RMID, NULL); exit(); } Пример. Работа с общей памятью в рамках одного процесса.
30 IPC: массив семафоров.
31 #include int semget (key_t key, int nsems, int semflag) Создание/доступ к семафору key – ключ nsems – количество семафоров semflag – флаги, определяющие права доступа и те операции, которые должны выполняться (открытие семафора, проверка, и т.д.). Возвращает целочисленный идентификатор созданного разделяемого ресурса, либо -1, если ресурс не удалось создать.
32 #include int semop (int semid, struct sembuf *semop, size_t nops) Операции над семафором semid – идентификатор ресурса semop – указатель на структуру, определяющую операции, которые нужно призвести над семафором nops– количество указателей на эту структуру, которые передаются функцией semop()
33 Операции над семафором struct sembuf { short sem_num; /*номер семафора в векторе*/ short sem_op; /*производимая операция*/ short sem_flg; /*флаги операции*/ } Значение семафора с номером num равно val. Если semop 0 то если val+semop < 0 то пока !(val+semop 0) [процесс стоит] val=val+semop Если semop = 0 то если val 0 то пока (val 0) [процесс стоит] [возврат из вызова]
34 #include int semctl (int semid, int num, int cmd, union semun arg) Управление массивом семафоров semid – дескриптор массива семафоров num – индекс семафора в массиве cmd – операция IPC_SET заменить управляющие наборы семафоров на те, которые указаны в arg.buf IPC_RMID удалить массив семафоров и др. arg – управляющие параметры Возвращает значение, соответствующее выполнявшейся операции (по умолчанию 0), в случае неудачи – -1
35 #include int semctl (int semid, int num, int cmd, union semun arg) Управление массивом семафоров union semun { int val; /* значение одного семафора *. struct semid_ds *buf; /* параметры массива семафоров в целом (количество, права доступа, статистика доступа)*/ ushort *array;/* массив значений семафоров */ }
36 Пример. Использование разделяемой памяти и семафоров.
37 1-ый процесс int main(int argc, char **argv) { key_t key; int semid, shmid; struct sembuf sops; char *shmaddr; char str[NMAX]; key = ftok(/usr/ter/exmpl, S); semid = semget(key, 1, 0666 | IPC_CREAT | IPC_EXCL); shmid = shmget(key, NMAX, 0666 | IPC_CREAT | IPC_EXCL); shmaddr = shmat(shmid, NULL, 0); … #include #define NMAX256
38 … semctl(semid, 0, SETVAL, (int) 0); sops.sem_num = 0; sops.sem_flg = 0; do { printf(Введите строку:); if (fgets(str, NMAX, stdin) == NULL) strcpy(str, Q); strcpy(shmaddr, str); sops.sem_op = 3; semop(semid, &sops, 1); sops.sem_op = 0; semop(semid, &sops, 1); } while (str[0] != Q); … shmdt(shmaddr); shmctl(shmid, IPC_RMID, NULL); semctl(semid, 0, IPC_RMID, (int) 0); return 0;} 1-ый процесс
39 2-ой процесс int main(int argc, char **argv) { key_t key; int semid, shmid; struct sembuf sops; char *shmaddr; char str[NMAX]; key = ftok(/usr/ter/exmpl, S); semid = semget(key, 1, 0666); shmid = shmget(key, NMAX, 0666); shmaddr = shmat(shmid, NULL, 0); sops.sem_num = 0; … #include #define NMAX256
40 … sops.sem_flg = 0; do { printf(Waiting… \n); sops.sem_op = -2; semop(semid, &sops, 1); strcpy(str, shmaddr); if (str[0] == Q) shmdt(shmaddr); sops.sem_op = -1; semop(semid, &sops, 1); printf(Read from shared memory: %s\n, str); } while (str[0] != Q); return 0; } 2-ой процесс
Еще похожие презентации в нашем архиве:
© 2024 MyShared Inc.
All rights reserved.