Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Обучение VC++ / ЛекцииИнтернетС++ / Лекция_лаб_практикум.doc
Скачиваний:
64
Добавлен:
16.02.2016
Размер:
932.35 Кб
Скачать

Пример 8. Разделение памяти.

Процесс sh1, создаёт область разделяемой памяти размером 256 Кбайт и дважды присоединяет её к своему адресному пространству по разным виртуальным адресам. В "первую" область он записывает данные, а читает их из "второй" области. Процесс sh2, присоединяет ту же область (он получает только 32 Кбайта, таким образом, каждый процесс может использовать разный объем области разделяемой памяти). Он ждет момента, когда sh1 запишет в первое принадлежащее области слово любое отличное от нуля значение, и затем считывает данные из области. Sh1 делает "паузу", предоставляя sh2 возможность выполнения; когда sh1 принимает сигнал, он удаляет область разделяемой памяти из системы.

sh1.c

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#define KEY 75

#define K 1024

void cleanup();

int shmid;

main()

{

int i, *pint;

for(i=1;i<23;i++)

signal(i,cleanup);

char *addr1, *addr2;

shmid = shmget(KEY,256*K,0777|IPC_CREAT);

addr1 = shmat(shmid,0,0);

addr2 = shmat(shmid,0,0);

printf("sh1:shmid=%d addr1=%x addr2=%x\n",shmid,addr1,addr2);

pint = (int *) addr1;

pint=getpid();pint++; /*Записать индекс sh1*/

for (i = 1; i<=5; i++)

*pint = i*2;

pint = (int *) addr2;

while (*pint!=0)

printf("sh1: адрес-%x\tзначение-%d\n",pint,*pint++);

pause();

}

void cleanup()

{

shmctl(shmid,IPC_RMID,0);

exit();

}

sh2.c

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#define KEY 75

#define K 1024

int shmid;

main()

{

int i, *pint;

char *addr;

nice(39); /* уменьшение приоритета */

do

{

shmid = shmget(KEY,32*K,0777);

}

while(shmid<=0);

addr = shmat(shmid,0,0);

pint = (int *) addr;

printf("sh2: shmid=%d адрес=%x \n",shmid,addr);

while (*pint == 0);

while (*pint != 0)

printf("sh2: адрес-%x\tзначение-%d\n",pint,*pint++);

kill(*pint,1); /* Освобождение линии (hangup) */

}

Пример 9. Использование семафоров.

Два процесса sem1.out и sem2.out запускаются последовательно

sem1.out & , а когда sem1 «заснёт»

sem2.out

sem1 создаёт массив из трёх семафоров, во все функцией semctl заносится по единице и проверяется занесение. Подготавливается массив структур V для функции sem­op, со значениями 1 2 3 и флагом, позволяющим в случае завершения процесса восстановить значения семафоров. В нулевом семафоре массива формируется число 2, а затем функция semop проверяет этот семафор на 0, и так как он не 0, процесс «засыпает».

sem2 выполняет команду semop обнуляя нулевой семафор и заканчивает работу, при этом sem1 “просыпается“ выводит состояния семафоров, причём, в нулевом будет ноль, уничтожает массив семафоров и заканчивает работу.

Если после запуска sem1 выполнить команду shell ps, то можно увидеть спящий sem1.out.

sem1.c

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/sem.h>

#define KEY 75

int semid;

void cleanup();

struct sembuf p,v[3]; /* операции типа P и V */

main()

{

int i;

short initarray[3],outarray[3];

for (i = 0; i < 20; i++)

signal(i,cleanup);

semid = semget(KEY,3,0777 | IPC_CREAT);

initarray[0] = initarray[1] = initarray[2] = 1;

semctl(semid,3,SETALL,initarray);

semctl(semid,3,GETALL,outarray);

printf("sem:начальные значения семафоров %d %d %d\n", outarray[0], outarray[1], outarray[2]); /* 1 1 1 */

v[0].sem_num=0;

v[0].sem_op=1;

v[0].sem_flg=SEM_UNDO;

v[1].sem_num=1;

v[1].sem_op=2;

v[1].sem_flg=SEM_UNDO;

v[2].sem_num=2;

v[2].sem_op=3;

v[2].sem_flg=SEM_UNDO;

semop(semid,v,3);

semctl(semid,3,GETALL,outarray);

printf("sem: значения семафоров %d %d %d\n", outarray[0], outarray[1], outarray[2]); /* 2 3 4 */

p.sem_num=0;

p.sem_op=0;

p.sem_flg=SEM_UNDO;

semop(semid,&p,1);

// Здесь процесс засыпает и ждёт, пока значение семафора[0] не станет равным 0.

semctl(semid,3,GETALL,outarray);

printf("sem1: значения семафоров %d %d %d\n", outarray[0], outarray[1], outarray[2]); /* 0 3 4 */

cleanup()

}

cleanup()

{

semctl(semid,2,IPC_RMID,0);

exit();

}

sem2.c

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/sem.h>

#define KEY 75

int semid;

struct sembuf v; /* операция типа V */

main()

{

int i;

short outarray[3];

semid = semget(KEY,3,0777);

semctl(semid,3,GETALL,outarray);

printf("sem2: значения семафоров %d %d %d\n", outarray[0], outarray[1], outarray[2]); /* 2 3 4 */

v.sem_num=0;

v.sem_op=-2;

v.sem_flg=SEM_UNDO;

semop(semid,&v,1);

semctl(semid,3,GETALL,outarray);

printf("sem2: значения семафоров %d %d %d\n", outarray[0], outarray[1], outarray[2]); /* 2 3 4 */

p.sem_num=0;

p.sem_op=0;

p.sem_flg=SEM_UNDO;

semop(semid,&p,1);

}