Система межпроцессного взаимодействия IPC

Содержание

Слайд 2

Общие концепции #include #include key_t ftok ( char * filename, char

Общие концепции

#include
#include
key_t ftok ( char * filename, char proj

)

filename — строка, cодержащая имя файла
proj — добавочный символ

Необходимые заголовочные файлы и прототип

Параметры

Слайд 3

Общие концепции get ( key, …, flags ) — создание/подключение Флаги

Общие концепции

get ( key, …, flags ) — создание/подключение
Флаги cоздания/подключения:
IPC_PRIVATE

(доступность только породившему процессу)
IPC_CREAT (создать новый или подключиться к существующему)
IPC_EXCL ( + IPC_CREAT создание только нового)

Слайд 4

IPC: очередь сообщений Общие концепции Создание/доступ к очереди сообщений Отправка сообщений

IPC: очередь сообщений

Общие концепции
Создание/доступ к очереди сообщений
Отправка сообщений
Получение сообщений
Управление очередью сообщений
Пример.

Использование очереди сообщений
Пример. Очередь сообщений .Модель «клиент-сервер»
Слайд 5

A B B B A A A Очередь сообщений Организация очереди

A

B

B

B

A

A

A

Очередь сообщений

Организация очереди сообщений по принципу FIFO
Использование типов сообщений

B

A

A

B

A

B

A

A

A

A

A

B

B

B

Слайд 6

Создание/доступ к очереди сообщений key — ключ msgflag — флаги, управляющие

Создание/доступ к очереди сообщений

key — ключ
msgflag — флаги, управляющие поведением вызова

В

случае успеха возвращается положительный дескриптор очереди, в случае неудачи возвращается –1.

#include
#include
#include
int msgget ( key_t key, int msgflag )

Необходимые заголовочные файлы и прототип

Параметры

Возвращаемое значение

Слайд 7

Отправка сообщений msqid — дескриптор очереди, полученный в результате вызова msgget()

Отправка сообщений

msqid — дескриптор очереди, полученный в результате вызова msgget()
msgp

— указатель на буфер:
long msgtype —тип сообщения
char msgtext[] — данные (тело сообщения)

#include
#include
#include
int msgsnd ( int msqid, const void * msgp, size_t msgsz, int msgflg )

Необходимые заголовочные файлы и прототип

Параметры

Слайд 8

Отправка сообщений msgsz — размер тела сообщения msgflg 0 процесс блокируется,

Отправка сообщений

msgsz — размер тела сообщения
msgflg
0 процесс блокируется, если для посылки

сообщения недостаточно системных ресурсов
IPC_NOWAIT – работа без блокировки (возврат –1)

#include
#include
#include
int msgsnd ( int msqid, const void * msgp, size_t msgsz, int msgflg )

Необходимые заголовочные файлы и прототип

Параметры

Слайд 9

Получение сообщений msqid — дескриптор очереди msgp — указатель на буфер

Получение сообщений

msqid — дескриптор очереди
msgp — указатель на буфер
msgsz

— размер тела сообщения
msgtyp — тип сообщения, которое процесс желает получить

#include
#include
#include
int msgrcv ( int msqid, void * msgp, size_t msgsz, long msgtyp, int msgflg )

Необходимые заголовочные файлы и прототип

Параметры

Слайд 10

Получение сообщений msgflg — побитовое сложение флагов IPC_NOWAIT — если сообщения

Получение сообщений

msgflg — побитовое сложение флагов
IPC_NOWAIT — если сообщения в очереди

нет, то возврат –1
MSG_NOERROR — разрешение получать сообщение, даже если его длина превышает емкость буфера

#include
#include
#include
int msgrcv ( int msqid, void * msgp, size_t msgsz, long msgtyp, int msgflg )

В случае успеха возвращает количество прочитанных байтов в теле сообщения.

Необходимые заголовочные файлы и прототип

Параметры

Возвращаемое значение

Слайд 11

Управление очередью сообщений msgid — дескриптор очереди cmd — команда IPC_STAT

Управление очередью сообщений

msgid — дескриптор очереди
cmd — команда
IPC_STAT — скопировать структуру,

описывающую управляющие параметры очереди по адресу, указанному в параметре buf
IPC_SET — заменить структуру, описывающую управляющие параметры очереди, на структуру, находящуюся по адресу, указанному в параметре buf
IPC_RMID — удалить очередь

#include
#include
#include
int msgctl ( int msqid, int cmd, struct msgid_ds * buf )

Необходимые заголовочные файлы и прототип

Параметры

Слайд 12

Управление очередью сообщений buf — структура, описывающая параметры очереди. #include #include

Управление очередью сообщений

buf — структура, описывающая параметры очереди.

#include
#include
#include
int

msgctl (int msqid, int cmd, struct msgid_ds *buf)

В случае успеха возвращается 0.

Тип msgid_ds описан в заголовочном файле , и представляет собой структуру, в полях которой хранятся права доступа к очереди, статистика обращений к очереди, ее размер и т.п.

Необходимые заголовочные файлы и прототип

Параметры

Возвращаемое значение

Слайд 13

Использование очереди сообщений int main ( int argc, char ** argv

Использование очереди сообщений

int main ( int argc, char ** 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
#include
#include
#include
struct
{
long mtype ;
char Data [ 256 ] ;
} Message ;

Основной процесс

Слайд 14

... switch ( str [ 0 ] ) { case ‘a’

...
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 ;
}
}
}

Использование очереди сообщений

Основной процесс

Слайд 15

int main ( int argc, char ** argv ) { key_t

int main ( int argc, char ** 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
#include
#include
#include
struct {
long mtype ;
char Data [ 256 ] ;
} Message ;

Использование очереди сообщений

Процесс-приемник А

Слайд 16

Пример: «Клиент-сервер» int main ( int argc, char ** argv )

Пример: «Клиент-сервер»

int main ( int argc, char ** argv )
{ struct

{
long mestype ;
char mes [ 100 ] ;
} messageto ;
struct {
long mestype ;
long mes ;
} messagefrom ;
key_t key ;
int mesid ;

#include
#include
#include
#include
#include

Сервер

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 ) ;
}
return 0 ;
}

Слайд 17

Пример: «Клиент-сервер» int main ( int argc, char ** argv )

Пример: «Клиент-сервер»

int main ( int argc, char ** argv )
{
struct {


long mestype;
long mes;
} messageto;
struct {
long mestype;
char mes[100];
} messagefrom;
key_t key;
int mesid;

#include
#include
#include

Клиент

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 ;
}

Слайд 18

#include #include #include int shmget ( key_t key, int size, int

#include
#include
#include
int shmget ( key_t key, int size, int

shmflg )

IPC: разделяемая память

key — ключ для доступа к разделяемой памяти
size — размер области памяти
shmflg — флаги управляющие поведением вызова

дескриптор области памяти, в случае неудачи — –1.

Создание общей памяти

Параметры

Возвращаемое значение

Слайд 19

#include #include #include char * shmat ( int shmid, char *

#include
#include
#include
char * shmat ( int shmid, char *

shmaddr, int shmflg )

Доступ к разделяемой памяти

shmid — дескриптор области памяти
shmaddr — «адрес подключения» - адрес, начиная с которого необходимо подсоединить разделяемую память (>0 или =0)
shmflg — флаги, например, SHM_RDONLY подсоединяемая область будет использоваться только для чтения

Возвращает адрес, начиная с которого будет отображаться при-соединяемая разделяемая память. При неудаче возвращается –1.

Необходимые заголовочные файлы и прототип

Параметры

Возвращаемое значение

Слайд 20

#include #include #include int shmdt ( char * shmaddr ) Отключение

#include
#include
#include  
int shmdt ( char * shmaddr )

Отключение от

разделяемой памяти

shmaddr — адрес прикрепленной к процессу памяти, который был получен при вызове shmat()

В случае успешного выполнения функция возвращает 0, в случае неудачи — –1.

Необходимые заголовочные файлы и прототип

Параметры

Возвращаемое значение

Слайд 21

#include #include #include int shmctl ( int shmid, int cmd, struct

#include
#include
#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 — структура, описывающая управляющие параметры области памяти.

Необходимые заголовочные файлы и прототип

Параметры

Слайд 22

int main ( int argc, char ** argv ) { key_t

int main ( int argc, char ** 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 ) ;
............................
shmctl ( shmid, IPC_RMID, NULL ) ;
exit () ;
}

Пример. Работа с общей памятью в рамках одного процесса

Слайд 23

IPC: массив семафоров

IPC: массив семафоров

Слайд 24

#include #include #include int semget ( key_t key, int nsems, int

#include
#include
#include
int semget ( key_t key, int nsems, int

semflag )

Создание/доступ к семафору

key — уникальный идентификатор ресурса
nsems — количество семафоров
semflag — флаги

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

Необходимые заголовочные файлы и прототип

Параметры

Возвращаемое значение

Слайд 25

#include #include #include int semop ( int semid, struct sembuf *cmd_buf

#include
#include
#include
int semop ( int semid, struct sembuf *cmd_buf

, size_t nops )

Операции над семафором

semid — дескриптор ресурса
cmd_buf — массив из элементов типа sembuf
nops — количество элементов в массиве cmd_buf

Необходимые заголовочные файлы и прототип

Параметры

Слайд 26

Операции над семафором struct sembuf { short sem_num ; /* номер

Операции над семафором

struct sembuf
{ short sem_num ; /* номер семафора */
short

sem_op ; /* операция */
short sem_flg ; /* флаги операции */
}

Значение семафора с номером num равно val.

Если sem_op ≠ 0 то
пока (val+sem_op < 0) [процесс блокирован]
val=val+sem_op
Если sem_op = 0 то
пока (val ≠ 0) [процесс блокирован]
[возврат из вызова]

Слайд 27

#include #include #include int semctl (int semid, int num, int cmd,

#include
#include
#include
int semctl (int semid, int num, int cmd,

union semun arg)

Управление массивом семафоров

semid — дескриптор массива семафоров
num — номер семафора в массиве
cmd — операция
IPC_SET изменить значение, параметры семафора
IPC_RMID удалить массив семафоров
и др.
arg — управляющие параметры

Возвращает значение, соответствующее выполнявшейся операции (по умолчанию 0), в случае неудачи — –1

Необходимые заголовочные файлы и прототип

Параметры

Возвращаемое значение

Слайд 28

#include #include #include int semctl (int semid, int num, int cmd,

#include
#include
#include
int semctl (int semid, int num, int cmd,

union semun arg)

Управление массивом семафоров


union semun
{
int val ; /* значение одного семафора */
struct semid_ds * buf ; /* параметры массива семафоров в целом (количество, права доступа, статистика доступа)*/
unsigned short * array ; /* массив значений семафоров */
}

Необходимые заголовочные файлы и прототип

Слайд 29

Пример. Использование разделяемой памяти и семафоров

Пример. Использование разделяемой памяти и семафоров

Слайд 30

Использование разделяемой памяти и семафоров int main ( int argc, char

Использование разделяемой памяти и семафоров

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
#include
#include
#include
#include
#define NMAX 256

1-ый процесс

Слайд 31

… semctl ( semid, 0, SETVAL, (int) 0 ) ; sops


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-ый процесс

Слайд 32

int main ( int argc, char ** argv ) { key_t

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
#include
#include
#include
#include
#define NMAX 256

Использование разделяемой памяти и семафоров

2-ой процесс