8105

Синхронизация процессов при помощи семафоров

Лабораторная работа

Информатика, кибернетика и программирование

Синхронизация процессов при помощи семафоров Цель работы: получить представление о синхронизации процессов в ОС UNIX при помощи флагов в разделяемой памяти и процессных семафоров. Иcпользуемые средства: ОС Linux, графическая оболочка KDE, среда разр...

Русский

2013-02-03

48 KB

5 чел.

Синхронизация процессов при помощи семафоров

Цель работы: получить представление о синхронизации процессов в ОС UNIX при помощи флагов в разделяемой памяти и процессных семафоров.

Иcпользуемые средства: ОС Linux, графическая оболочка KDE, среда разработки Anjuta, терминал.

1. Создать два процесса: приемник и передатчик. Передатчик увеличивает на единицу переменную целого типа в разделяемой памяти, а приемник выводит ее значение на экран. Для синхронизации использовать переменные в разделяемой памяти. Задать 100 повторений цикла обмена.

Передатчик:

#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/stat.h>
#define mem 0xABCD

int* c;
int dmem;
char* pmem;
int* f_t;
int* f_r;
int* end;
int main()
{
 dmem=shmget(mem,getpagesize(),IPC_CREAT|S_IRUSR|S_IWUSR);
 pmem=(
char*)shmat(dmem,0,0);
    c=(
int*)pmem;
  f_t=(
int*)(pmem+sizeof(int));
  f_r=(
int*)(pmem+sizeof(int)+sizeof(int));
  end=(
int*)(pmem+sizeof(int)+sizeof(int)+sizeof(int));
 printf(
"Go-o-o-o !!!\n\t");

 
while(!*end){
   *f_t=
1;               
   
while(!*f_r);         
   (*c)++;               
   printf(
"%d\n\t",*c);  
   *f_t=
0;               
   
while(*f_r);          
 }
 
if(!shmdt(pmem)) printf("MEMORY CLOSE ALL RIGHT\n");
   
else printf("MEMORY ERROR!!!\n");
 
return 0;
}

Приемник:

#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/stat.h>
#define mem 0xABCD

int* c;
int dmem;
char* pmem;
int* f_t;
int* f_r;
int* end;
int main()
{
 dmem=shmget(mem,getpagesize(),IPC_CREAT|S_IRUSR|S_IWUSR);
 pmem=(
char*)shmat(dmem,0,0);
    c=(
int*)pmem;
  f_t=(
int*)(pmem+sizeof(int));
  f_r=(
int*)(pmem+sizeof(int)+sizeof(int));
  end=(
int*)(pmem+sizeof(int)+sizeof(int)+sizeof(int));
 *c=
0;*f_t=0;*f_r=0;*end=0;
 printf(
"Priemnic on start\n\t");
 
while(*c<20)
   {
   
while(!*f_t);             
   *f_r=
1;                       
   
while(*f_t);                  
   printf(
"%d\n\t",*c);          
   *f_r=
0;                       
   }
 *end=
1;
 
return 0;
}

2. Выполнить обмен данными между процессами как в пункте 1, но для синхронизации использовать процессный семафор.

Передатчик:

#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sem.h>
#define mem 0xABCD
#define sem 0x1234

int* c;
int dmem;
char* pmem;
int* end;
int idsem;
union semun {
 
int val;
 
struct semid_ds *buf;
 
unsigned short *array;
 
struct seminfo *__buf;
} semini;
struct sembuf smb;
int main()
{
 idsem=semget(sem,
1,IPC_CREAT|S_IRUSR|S_IWUSR);
 semini.val=
0;
 smb.sem_num=
0;
 semctl(idsem,
0,SETVAL,semini);
 dmem=shmget(mem,getpagesize(),IPC_CREAT|S_IRUSR|S_IWUSR);
 pmem=(
char*)shmat(dmem,0,0);
    c=(
int*)pmem;
  end=(
int*)(pmem+sizeof(int));
 printf(
"Go-o-o-o !!!\n");
 
while(!*end){
   smb.sem_op=
1;
   semop(idsem,&smb,
1);
   smb.sem_op=
0;
   semop(idsem,&smb,
1);
   (*c)++; printf(
"%d\n",*c);
   smb.sem_op=
1;
   semop(idsem,&smb,
1);
   smb.sem_op=
0;
   semop(idsem,&smb,
1);
 }
 
if(!shmdt(pmem)) printf("MEMORY CLOSE ALL RIGHT\n");
   
else printf("MEMORY ERROR!!!\n");
 semctl(idsem,
0,IPC_RMID,semini);
 
return 0;
}

Приемник:

#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sem.h>
#define mem 0xABCD
#define sem 0x1234

int* c;
int dmem;
char* pmem;
int* end;
int idsem;
union semun {
 
int val;
 
struct semid_ds *buf;
 
unsigned short *array;
 
struct seminfo *__buf;
} semini;
struct sembuf smb;

int main()
{
 
idsem=semget(sem,1,IPC_CREAT|S_IRUSR|S_IWUSR);
 
semini.val=0;
 
smb.sem_num=0;
 
semctl(idsem,0,SETVAL,semini);
 
dmem=shmget(mem,getpagesize(),IPC_CREAT|S_IRUSR|S_IWUSR);
 
pmem=(char*)shmat(dmem,0,0);
    
c=(int*)pmem;
  
end=(int*)(pmem+sizeof(int));
 *
c=0;*end=0;
 
printf("Priemnic on start\n\t");
 
while(*c<1000)
   {
     
smb.sem_op=-1;
     
semop(idsem,&smb,1);
     
smb.sem_op=-1;
     
semop(idsem,&smb,1);
     
printf("%d\n",*c);
   }
 *
end=1;
 
return 0;
}

3. Создать 3 процесса: диспетчер, регулятор и модель и обеспечить их синхронизацию при помощи процессных семафоров таким образом, чтобы на каждые 5 шагов модели приходился один шаг регулятора. Модель на каждом шаге увеличивает на единицу переменную целого типа в разделяемой памяти, а регулятор выводит значение этой переменной на экран.

 

Диспетчер:

#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sem.h>
#define mem 0xAAAA
#define sem 0x4567

int* c;
int* ch;
int dmem;
char* pmem;
int* end;
int idsem;
union semun {
 
int val;
 
struct semid_ds *buf;
 
unsigned short *array;
 
struct seminfo *__buf;
} semini;
struct sembuf smb;

int main()
{
 idsem=semget(sem,
3,IPC_CREAT|S_IRUSR|S_IWUSR);
 semini.val=
0;
 smb.sem_num=
0;
 semctl(idsem,
0,SETVAL,semini);
 smb.sem_num=
1;
 semctl(idsem,
1,SETVAL,semini);
 smb.sem_num=
2;
 semctl(idsem,
2,SETVAL,semini);

 dmem=shmget(mem,getpagesize(),IPC_CREAT|S_IRUSR|S_IWUSR);
 pmem=(
char*)shmat(dmem,0,0);
    c=(
int*)pmem;
  end=(
int*)(pmem+sizeof(int));
   ch=(
int*)(pmem+sizeof(int)+sizeof(int));

 printf(
"Dispetcher on start\n\n");

 smb.sem_num=
0;
 smb.sem_op=
2;
 semop(idsem,&smb,
1);

 
while(*c<500)
   {
   smb.sem_num=
1;
   smb.sem_op=
5;
   semop(idsem,&smb,
1);
   smb.sem_op=
0;
   semop(idsem,&smb,
1);


   smb.sem_num=
2;
   smb.sem_op=
1;
   semop(idsem,&smb,
1);
   smb.sem_op=
0;
   semop(idsem,&smb,
1);

   fprintf(stderr,
"\t| %d\t| %d\t|\n",*c,*ch);
   }
 *end=
1;
 printf(
"\t|_______|_______|\n\n");

 
if(!shmdt(pmem)) printf("MEMORY CLOSE ALL RIGHT\n");
   
else printf("MEMORY ERROR!!!\n");
 
if(!semctl(idsem,0,IPC_RMID,semini)) printf("SEMAFORS CLOSE ALL RIGHT\n");
   
else printf("SEMAFORS ERROR!!!\n");
 
return 0;
}

Передатчик:

#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sem.h>
#define mem 0xAAAA
#define sem 0x4567

int* c;
int* ch;
int dmem;
char* pmem;
int* end;
int idsem;
union semun {
 
int val;
 
struct semid_ds *buf;
 
unsigned short *array;
 
struct seminfo *__buf;
} semini;
struct sembuf smb;

int main()
{
 idsem=semget(sem,
3,IPC_CREAT|S_IRUSR|S_IWUSR);
 semini.val=
0;
 smb.sem_num=
1;
 semctl(idsem,
1,SETVAL,semini);

 dmem=shmget(mem,getpagesize(),IPC_CREAT|S_IRUSR|S_IWUSR);
 pmem=(
char*)shmat(dmem,0,0);
    c=(
int*)pmem;
  end=(
int*)(pmem+sizeof(int));
   ch=(
int*)(pmem+sizeof(int)+sizeof(int));

 printf(
"Peredatchic on start\n\n");

 smb.sem_num=
0;
 smb.sem_op=-
1;
 semop(idsem,&smb,
1);


 
while(!*end)
   {
   smb.sem_num=
1;
   smb.sem_op=-
1;
   semop(idsem,&smb,
1);
   (*c)++;
   printf(
"\t| %d\t|\n",*c);
   }
 
return 0;
}

Приемник:

#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sem.h>
#define mem 0xAAAA
#define sem 0x4567

int* c;
int* ch;
int dmem;
char* pmem;
int* end;
int idsem;
union semun {
 
int val;
 
struct semid_ds *buf;
 
unsigned short *array;
 
struct seminfo *__buf;
} semini;
struct sembuf smb;
int main()
{
 idsem=semget(sem,
3,IPC_CREAT|S_IRUSR|S_IWUSR);
 semini.val=
0;
 smb.sem_num=
2;
 semctl(idsem,
2,SETVAL,semini);

 dmem=shmget(mem,getpagesize(),IPC_CREAT|S_IRUSR|S_IWUSR);
 pmem=(
char*)shmat(dmem,0,0);
    c=(
int*)pmem;
  end=(
int*)(pmem+sizeof(int));
   ch=(
int*)(pmem+sizeof(int)+sizeof(int));
 *c=
0;*end=0;*ch=0;

 printf(
"Priemnic on start\n\n");
 smb.sem_num=
0;
 smb.sem_op=-
1;
 semop(idsem,&smb,
1);

 
while(!*end){
   smb.sem_num=
2;
   smb.sem_op=-
1;
   semop(idsem,&smb,
1);
   (*ch)++;
   fprintf(stderr,
"\t| %d\t|\n",*ch);
 }
 *end=
1;
 
return 0;
}


 

А также другие работы, которые могут Вас заинтересовать

71051. Обработка двумерных массивов 323.5 KB
  Задание к лабораторной работе: Дана действительная квадратная матрица А размера n  n. Вычислить суммы элементов двух главных диагоналей матрицы. Схема алгоритма. Программа на языке Basic Расчет сумм элементов двух главных диагоналей матрицы.
71053. Программирование типовых алгоритмов 203.5 KB
  Задание к лабораторной работе Ввести восемь чисел и вычислить наибольшее среди четных чисел и его номер. Схема алгоритма. Программа на языке Basic Типовые алгоритмы CLS PRINT “Вычисление наибольшего четного числа из восьми введенных“ n = 8 max = -100000...
71054. Программирование простых циклических процессов 148.5 KB
  Составить таблицу значений массы жидкого продукта в емкости, имеющей форму параллелепипеда в зависимости от высоты жидкости в емкости. Высота меняется от 0,5 м до 2 м с шагом 0,5 м. Схема алгоритма. Программа на языке Basic...
71056. Исследование LC-автогенератора 272.5 KB
  Исследовать работу генератора в режиме синхронизации колебаний захват частоты. Путём изменения частоты генератора для различных значений фиксированного напряжения внешнего генератора экспериментально определяется область синхронизации автогенератора.
71058. Створення та виконання різних запитів 4.68 MB
  Запит на створення таблиці Запит на додавання запису Запит на оновлення запису Запит на видалення запису Запити в режимі SQL Простий запит на вибірку Завдання 3. DROP TBLE Копия Відділення; Запит який повертає список викладачів та студентів...