WWW.DISSERS.RU

БЕСПЛАТНАЯ ЭЛЕКТРОННАЯ БИБЛИОТЕКА

   Добро пожаловать!


Pages:     | 1 |   ...   | 30 | 31 ||

psmb.sem_num = psmb.sem_flg = psmb.sem_op = 0;

semop(semid,&psmb,1);

printf("Parent: Semaphore is unlocked...\n");

printf("Parent: Waiting for SIGCHILD...\n");

waitpid(pid,NULL,0);

printf("Parent: Deleting semaphore...\n");

semctl(semid, 0, IPC_RMID);

exit(0);

} Запуск приведенной выше программы происходит следующим образом:

semsyn Parent: Creating semaphore...

Parent: Getting info about semaphore (not required, for example)...

Parent: Creating time - 13 : 14 : Parent: Setting value " 5 " to semaphore...

Parent: Creating child process...

Child: Child process was created...

Child: Opening semaphore...

Child: Locking semaphore...

Child: Do something...

Parent: Waiting for unlocking semaphore...

Child: Done something...

Child: Semaphore value = Child: Unlocking semaphore...

Parent: Semaphore is unlocked...

Parent: Waiting for SIGCHILD...

Child: Terminating child process...

Parent: Deleting semaphore...

Во время работы программы создается семафор с живучестью ядра ipcs –s ------ Semaphore Arrays -------- key semid owner perms nsems 0x000004d2 425986 root 644 Разделяемая память Программа shmget создает сегмент разделяемой памяти, принимая из командной строки полное имя произвольного файла и длину сегмента.

#include #include #include #include #include #include #include #define SVSHM_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) int main(int argc, char **argv) { int c, id, oflag;

сhar *ptr;

size_tlength;

oflag = SVSHM_MODE | IPC_CREAT; // флаг создания семафора while ( (c = getopt(argc, argv, "e")) != -1) { switch (c) { // просмотр ключей командной строки case 'e':

oflag |= IPC_EXCL;

break;

} } if (optind != argc - 2) { printf("usage: shmget [ -e ] ");

return 0;

} length = atoi(argv[optind + 1]);

id = shmget(ftok(argv[optind], 0), length, oflag);

ptr = (char*) shmat(id, NULL, 0);

return 0;

} Вызов shmget создает сегмент разделяемой памяти указанного размера. Полное имя, передаваемое в качестве аргумента командной строки, преобразуется в ключ IPC System V вызовом функции ftok. Если указан параметр е командной строки и в системе существует сегмент с тем же именем, запуски программы завершатся по ошибке. Если известно, что сегмент уже существует, то в командной строке должна быть указана нулевая длина сегмента памяти.

Вызов shmat подключает сегмент к адресному пространству процесса, после чего программа завершает работу. В связи с тем, что разделяемая память System V обладает «живучестью ядра», то сегмент разделяемой памяти при этом не удаляется.

Программа shmrmid вызывает функцию shmctl с командой IPC_RMID для удаления сегмента разделяемой памяти из системы.

#include #include #include #include #include #define SVSHM_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) int main(int argc, char **argv) { int id;

if (argc != 2) { printf("usage: shmrmid ");

return 0;

} id = shmget(ftok(argv[1], 0), 0, SVSHM_MODE);

shmctl(id, IPC_RMID, NULL);

return 0;

} Программа shmwrite заполняет сегмент разделяемой памяти последовательностью значений 0, 1, 2,..., 254, 255. Сегмент разделяемой памяти открывается вызовом shmget и подключается вызовом shmat. Его размер может быть получен вызовом shmctl с командой IPC_STAT.

#include #include #include #include #include #define SVSHM_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) int main(int argc, char **argv) { int i, id;

struct shmid_ds buff;

unsigned char *ptr;

if (argc != 2) { printf("usage: shmwrite ");

return 0;

} id = shmget(ftok(argv[1], 0), 0, SVSHM_MODE);

ptr = (unsigned char*) shmat(id, NULL, 0);

shmctl(id, IPC_STAT, &buff);

/* 4set: ptr[0] = 0, ptr[1] = 1, etc. */ for (i = 0; i < buff.shm_segsz; i++) *ptr++ = i % 256;

return 0;

} Программа shmread проверяет последовательность значений, записанную в разделяемую память программой shmwrite.

#include #include #include #include #include #include #define SVSHM_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) int main(int argc, char **argv) { int i, id;

struct shmid_ds buff;

unsigned char c, *ptr;

if (argc != 2) { printf("usage: shmread ");

return 0;

} id = shmget(ftok(argv[1], 0), 0, SVSHM_MODE);

ptr = (unsigned char*) shmat(id, NULL, 0);

shmctl(id, IPC_STAT, &buff);

/* check that ptr[0] = 0, ptr[1] = 1, and so on. */ for (i = 0; i < buff.shm_segsz; i++) if ( (c = *ptr++) != (i % 256)) printf("ptr[%d] = %d", i, c);

return 0;

} Рассмотрим результат запуска приведенных выше программ при работе с разделяемой памятью. Вначале создается сегмент разделяемой памяти длиной 1234 байта. Для идентификации сегмента используем полное имя исполняемого файла /tmp/test1. Это имя будет передано функции ftok:

shmget /tmp/test1 ipcs -bmo IPC status from as of Thu Jan 8 13:17:06 T ID KEY MODE OWNER GROUP NATTCH SEGSZ Shared Memory:



m 1 0x0000fl2a --rw-r--r-- rstevens otherl 0 Программа ipcs запускается для того, чтобы убедиться, что сегмент разделяемой памяти действительно был создан и не был удален по завершении программы shmcreate.

Запуская программу shmwrite, можно заполнить содержимое разделяемой памяти последовательностью значений. Затем с помощью программы shmread проверяется содержимое сегмента разделяемой памяти:

shmwrite shmget shmread shmget shmrmid shmget ipcs -bmo IPC status from as of Thu Jan 8 13:17:06 T ID KEY MODE OWNER GROUP NATTCH SEGSZ Shared Memory:

Удалить разделяемую память можно, вызвав shmrmid /tmp/testПрограммные каналы Программа pipes создает два процесса и обеспечивает двустороннюю связь между ними посредством неименованных каналов.

#include #include #include #include #include #include #include #define MAXLINE void server(int,int), client(int,int);

int main(int argc, char **argv) { int pipe1[2],pipe2[2]; // идентификаторы каналов pid_t childpid = 0;

printf("Parent: Creating pipes...\n");

pipe(pipe1);

pipe(pipe2);

printf("Parent: Pipes created...\n");

printf("Parent: Creating child process...\n");

if ((childpid = fork()) == 0) { // child process starts printf("Child: Child process created...\n");

close(pipe1[1]);

close(pipe2[0]);

printf("Child: Starting server...\n");

server(pipe1[0], pipe2[1]);

printf("Child: Terminating process...\n");

exit(0);

} // parent process close(pipe1[0]);

close(pipe2[1]);

sleep(2);

printf("Parent: Starting client...\n");

client(pipe2[0],pipe1[1]);

printf("Parent: Waiting for child porecess to terminate a zombie...\n");

waitpid(childpid, NULL, 0);

printf("Parent: Zombie terminated...\n");

return 0;

} void server(int readfd, int writefd) { char str[MAXLINE];

strcpy(str,"some string to transmit");

ssize_t n = 0;

printf("%s %s %s","Child: Server: Tranferting string to client - \"",str,"\"\n");

write(writefd, str, strlen(str));

sleep(1);

printf("Child: Server: Waiting for replay from client...");

while ((n = read(readfd,str,MAXLINE)) > 0) { str[n] = 0;

printf("%s %s %s","Received OK from client - \"",str,"\"\n");

break;

} printf("Child: Server was terminated...\n");

return;

} void client(int readfd, int writefd) { ssize_t n = 0;

char buff[MAXLINE];

while ((n = read(readfd, buff, MAXLINE)) > 0 ) { buff[n] = 0;

printf("%s %s %s","Client: Recieved string from server: \"",buff,"\"\n");

break;

} printf("Parent: Client: Sending OK to server\n");

sleep(1);

strcpy(buff,"sends OK from client");

write(writefd, buff, strlen(buff));

return;

} Далее приведены программы, организующие межпроцессное взаимодействие посредством именованных каналов.

Программа сервер #include #include #include #include #include #include #include #include #include #include #include #define MAXLINE #define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) #define FIFO1 “/tmp/fifo.1” #define FIFO2 “/tmp/fifo.2” int main(int argc, char **argv) { int readfd = -1,writefd = -1;

pid_t childpid = 0;

ssize_t n;

char str[MAXLINE];

strcpy(str," some string to transmit ");

cout<<"Creating pipes..."<

unlink(FIFO1);

unlink(FIFO2);

if (mkfifo(FIFO1, FILE_MODE) == EEXIST) cout<<"\n Pipes is exists"<

if (mkfifo(FIFO2, FILE_MODE) == EEXIST) cout<<"\n Pipes is exists"<

cout<<"Pipes created..."<

writefd = open(FIFO2, O_WRONLY);

if ((writefd != -1)) { cout<<"Transmitting the string..."<

write(writefd,str,strlen(str));

readfd = open(FIFO1, O_RDONLY);

cout<<"Waiting for respond..."<

while ((n = read(readfd,str, MAXLINE)) > 0) { str[n] = 0;

cout<<"Received string - \""<

break;

} close(readfd);

close(writefd);

unlink(FIFO1);

unlink(FIFO2);

} else cout<<"Can't open pipes..."<

return 1;

} Программа клиент #include #include #include #include #include #include #include #include #include #include #include #define MAXLINE #define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) #define FIFO1 "/tmp/fifo.1" #define FIFO2 "/tmp/fifo.2" int main(int argc, char **argv) { int readfd = -1,writefd = -1;

pid_t childpid = 0;

ssize_t n = 0;

char str[MAXLINE];

ofstream fsw("./rezult.txt");

fsw<<"Opening pipes..."<

while (1) { readfd = open(FIFO2, O_RDONLY, 0);

if (readfd != -1) { fsw<<"Pipes opened..."<

fsw<<"Waiting for respond..."<

while ((n = read(readfd,str, MAXLINE)) > 0) { str[n] = 0;

fsw<<"Received string - \""<





break;

} strcpy(str,"Ok from other process");

writefd = open(FIFO1, O_WRONLY, 0);

fsw<<"Transmitting the string - \""<

write(writefd,str,strlen(str));

close(readfd);

close(writefd);

break;

} sleep(1);

} fsw.close();

return 1;

} Рассмотрим результат запуска приведенных выше программ, использующих неименованные каналы.

pipes Parent: Creating pipes...

Parent: Pipes created...

Parent: Creating child process...

Child: Child process created...

Child: Starting server...

Child: Server: Tranferting string to client - " some string to transmit " Child: Server: Waiting for replay from client...Received OK from client - " sends OK from client " Child: Server was terminated...

Child: Terminating process...

Parent: Creating pipes...

Parent: Pipes created...

Parent: Creating child process...

Parent: Starting client...

Client: Recieved string from server: " some string to transmit " Parent: Client: Sending OK to server Parent: Waiting for child porecess to terminate a zombie...

Parent: Zombie terminated...

Программы, взаимодействующие через каналы FIFO, запускаются следующим образом:

client & Opening pipes...

Pipes opened...

Waiting for respond...

Received string - " some string to transmit " Transmitting the string - "Ok from other process" server Creating pipes...

Pipes created...

Transmitting the string...

Waiting for respond...

Received string - "Ok from other process" [1]+ Exit 1./pn (wd: ~/makegnu/ipc/pipe_name/2/bin) (wd now: ~/makegnu/ipc/pipe_name/1/bin) Очереди сообщений Программа msgcreate создает очередь сообщений. Параметр командной строки е позволяет указать флаг IPC_EXCL. Полное имя файла, являющееся обязательным аргументом командной строки, передается функции ftok. Получаемый ключ преобразуется в идентификатор функцией msgget.

#include #include #include #include #include #include #include #define SVMSG_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) int main(int argc, char **argv) { int c, oflag, mqid;

oflag = SVMSG_MODE | IPC_CREAT;

while ( (c = getopt(argc, argv, "e")) != -1) { switch (c) { case 'e':

oflag |= IPC_EXCL;

break;

} } if (optind != argc - 1) { printf("usage: msgcreate [ -e ] ");

return 0;

} mqid = msgget(ftok(argv[optind], 0), oflag);

return 0;

} Программа msgsnd помещает в очередь одно сообщение заданной длины и типа. В программе создается указатель на структуру msgbuf общего вида, а затем путем вызова callос выделяется место под реальную структуру (буфер записи) соответствующего размера.

#include #include #include #include #include #include #include #define MSG_W (S_IWUSR) int main(int argc, char **argv) { int mqid;

size_t len;

long type;

struct msgbuf *ptr;

if (argc != 4) { printf("usage: msgsnd <#bytes>");

return 0;

} len = atoi(argv[2]);

type = atoi(argv[3]);

mqid = msgget(ftok(argv[1], 0), MSG_W);

ptr = (msgbuf*) calloc(sizeof(long) + len, sizeof(char));

ptr->mtype = type;

msgsnd(mqid, ptr, len, 0);

return 0;

} Программа msgrcv считывает сообщение из очереди. В командной строке может быть указан параметр n, отключающий блокировку, а параметр t может быть использован для указания типа сообщения в функции msgrcv.

#include #include #include #include #include #include #define MSG_R (S_IRUSR | S_IRGRP | S_IROTH) #define MAXMSG (8192 + sizeof(long)) int main(int argc, char **argv) { int c, flag, mqid;

long type;

ssize_t n;

struct msgbuf *buff;

type = flag = 0;

while ( (c = getopt(argc, argv, "nt:")) != -1) { switch (c) { case 'n':

flag |= IPC_NOWAIT;

break;

case 't':

type = atol(optarg);

break;

} } if (optind != argc - 1) { printf("usage: msgrcv [ -n ][ -t type ]");

return 0;

} mqid = msgget(ftok(argv[optind], 0), MSG_R);

buff = (msgbuf*) malloc(MAXMSG);

n = msgrcv(mqid, buff, MAXMSG, type, flag);

printf("read %d bytes, type = %ld\n", n, buff->mtype);

return 0;

} Программа msgctl удаляет очередь.

#include #include #include #include #include int main(int argc, char **argv) { int mqid;

if (argc != 2) { printf("usage: msgrmid ");

return 0;

} mqid = msgget(ftok(argv[1], 0), 0);

msgctl(mqid, IPC_RMID, NULL);

return 0;

} Результат запуска приведенных выше программ для случая с тремя сообщениями в очереди:

msgcreate /tmp/no/such/file ftok error for pathname "tmp/no/such/file" and id 0: No such file or directory touch /tmp/testl msgcreate /tmp/testl msgsnd /tmp/testl 1 msgsnd /tmp/testl 2 msgsnd /tmp/testl 3 ipcs -qo IPC status from as of Sat Jan 10 11:25:45 T ID KEY MODE OWNER GROUP CBYTES QNUM Message Queues:

Pages:     | 1 |   ...   | 30 | 31 ||










© 2011 www.dissers.ru - «Бесплатная электронная библиотека»

Материалы этого сайта размещены для ознакомления, все права принадлежат их авторам.
Если Вы не согласны с тем, что Ваш материал размещён на этом сайте, пожалуйста, напишите нам, мы в течении 1-2 рабочих дней удалим его.