2268

Синхронизация процессов. Обмен данными между процессами

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

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

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

Русский

2013-01-06

56 KB

12 чел.

Министерство образования РФ

Костромской Государственный Технологический Университет

Кафедра АМТ

Курс «Управляющие системы реального времени»

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

Синхронизация процессов. Обмен данными между процессами

Выполнил:  Швайко А.В.

Группа:       99-А-18 «а»

Проверил:   Ершов В.Н.

Кострома 2003

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

 

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

 

1. Составить программу, содержащую бесконечный цикл с вызовом sleep и выводом на экран. Заблокировать сигнал SIGINT при помощи

а. Функции signal

б. Критической секции

Убедиться, что программа не реагирует на Control-C.

а)

#include <stdio.h>
#include <signal.h>
int main()
{
 
int c;
 c=
0;
 signal(SIGINT, SIG_IGN);
 
while(1)
 {
   sleep(
1);
   fprintf(stderr,
"We want to write programs on C++ %d\n",c++);
 }
 
return 0;
}

б)

#include <stdio.h>
#include <signal.h>
int main()
{
 
int c;
 sigset_t mysig;
 c=
0;
 sigaddset(&mysig, SIGINT);
 sigprocmask(SIG_SETMASK, &mysig, NULL);
 
while(1)
 {
   sleep(
1);
   fprintf(stderr,
"We want to write programs on C++ %d\n",c++);
 }
 sigprocmask(SIG_UNBLOCK, &mysig, NULL);
 
return 0;
}

2. Модифицировать программу, установив обработчик сигнала SIGINT, выводящий на экран запрос на подтверждение завершения программы и по получении положительного ответа вызывающий функцию exit. Убедиться, что нажатие на Control C досрочно завершает сон процесса.

#include <stdio.h>
#include <signal.h>
void obrab(int key)
{
 printf(
"Are you ready to stop process. Yes-1, No-0\n");
 scanf(
"%d",&key);
 
if (key == 1) exit(0);
}
int main()
{
 
int c;
 c=
0;
 signal(SIGINT, obrab);
 
while(1)
 {
   sleep(
1);
   fprintf(stderr,
"We want to write programs on C++ %d\n",c++);
 }
 
return 0;
}

3. Модифицировать обработчик сигнала SIGINT таким образом, чтобы он вызывал exit после получения третьего сигнала.

#include <stdio.h>
#include <signal.h>
int n=0;
int obrab()
{
 n++;
 printf(
"Control-C number=%d\n",n);
 
if (n==3) exit (0);
}
int main()
{
 
int c;
 c=
0;
 signal(SIGINT, obrab);
 
while(1)
 {
   sleep(
1);
   fprintf(stderr,
"We want to write programs on C++ %d\n",c++);
 }
 
return 0;
}

4. Модифицировать бесконечный цикл основной программы таким образом, чтобы вызов sleep и вывод на экран находились внутри критической секции (но не весь цикл). Убедиться, что пока процесс «спит» внутри критической секции, для него откладывается только один сигнал SIGINT, независимо от числа нажатий на Control C.

#include <stdio.h>
#include <signal.h>
int n=0;
int obrab()
{
 n++;
 printf(
"Control-C number=%d\n",n);
 
if (n==3) exit (0);
}
int main()
{
 
int c;
 sigset_t mysig;
 sigaddset(&mysig,SIGINT);
 c=
0;
 signal(SIGINT, obrab);
 
while(1)
 {
   sigprocmask(SIG_SETMASK, &mysig, NULL);
   fprintf(stderr,
"In critical part%d\n",c++);
   sleep(
3);
   sigprocmask(SIG_UNBLOCK, &mysig, NULL);
 }
 
return 0;
}

5. Составить программу, устанавливающую обработчик сигнала от таймера реального времени и устанавливающую интервал между сигналами в 1,5 сек. Для контроля работы программы поместить в обработчик сигнала вывод на экран кода 0х07 (звуковой сигнал) или какой-либо строки. Перевести основную программу в

неактивное состояние

а. Вызовом pause()

б. Циклом while(1) pause()

Сравнить результаты.

#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
int c;
void obrab()
{
 
char sig=0x07;
 c+=
1;
 fprintf(stderr,
"%cSignal number\t%d\n",sig,c);
}
int main()
{
 
struct itimerval tm;
    tm.it_value.tv_sec=
0;
    tm.it_value.tv_usec=
500000;
    tm.it_interval.tv_sec=
1;
    tm.it_interval.tv_usec=
500000;
   setitimer(ITIMER_REAL,&tm,NULL);
   signal(SIGALRM, obrab);
 
while(1) pause();
 
//pause();
 
return (0);
}

6.Составить 2 программы, обменивающиеся информацией через разделяемую память. Достаточно использовать одну переменную целого типа для обмена информацией и одну переменную целого типа для синхронизации. Оба процесса устанавливают обработчики от таймера реального времени. Первый с интервалом 0.2 сек, второй – 1 сек. Обработчик сигнала от таймера в первом процессе инкрементирует переменную в разделяемой памяти, а второй – выводит значение этой переменной на экран. Оба процесса должны завершиться после срабатывания обработчика сигнала от таймера во втором процессе 15-20 раз.

Передатчик:

#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 0xAAAA

int* c;
int dmem;
char* pmem;
int* start;
int* end;

void obrab()
{
 fprintf(stderr,
"%d\n",*c);
 *c+=
1;
}
int main()
{
 
struct itimerval tm;
  tm.it_value.tv_sec=
0;
  tm.it_value.tv_usec=
500000;
  tm.it_interval.tv_sec=
0;
  tm.it_interval.tv_usec=
200000;
 setitimer(ITIMER_REAL,&tm,NULL);
 signal(SIGALRM, SIG_IGN);
 dmem=shmget(mem,getpagesize(),IPC_CREAT|S_IRUSR|S_IWUSR);
 pmem=(
char*)shmat(dmem,0,0);
 start=(
int*)pmem;
 c=(
int*)(pmem+sizeof(int));
 end=(
int*)(pmem+sizeof(int)+sizeof(int));

 signal(SIGALRM,obrab);
 *start=
0;

 
while(!*end) pause();
 *c=
0; *end=0;
 shmdt(pmem);
 
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 0xAAAA
int* c;
int dmem;
char* pmem;
int* start;
int* end;
int ch;

void obrab()
{
 ch+=
1;
 fprintf(stderr,
"%d\t%d\n",*c,ch);
}
int main()
{
 
struct itimerval tm;
  tm.it_value.tv_sec=
0;
  tm.it_value.tv_usec=
200000;
  tm.it_interval.tv_sec=
1;
  tm.it_interval.tv_usec=
0;
 setitimer(ITIMER_REAL,&tm,NULL);
 signal(SIGALRM, SIG_IGN);
 dmem=shmget(mem,getpagesize(),IPC_CREAT|S_IRUSR|S_IWUSR);
 pmem=(
char*)shmat(dmem,0,0);
 start=(
int*)pmem;
 c=(
int*)(pmem+sizeof(int));
 end=(
int*)(pmem+sizeof(int)+sizeof(int));

 *end=
0;
 *start=
1;
 
while(*start);
 signal(SIGALRM, obrab);

 
while(ch<15) pause();
 *end=
1;
 
return 0;
}

7. Переработать схему взаимодействия «модели» и «регулятора». Для этого заменить сигналы от таймера пользовательскими сигналами. А источником пользовательских сигналов сделать третий процесс «диспетчер», который будет в цикле, исполняемом 15-20 раз, посылать 5 сигналов «модели» и 1 сигнал «регулятору».

    а) выполнить посылку сигналов от «диспетчера» к «модели» и «регулятору» без подтверждения приема:

for(i=0; i< 20; i++){
   kill(*p_reg, SIGUSR2); 

   for(j=0; j<5; j++)kill(*p_mod, SIGUSR1);
}

убедиться, что схема не работает. Объяснить почему.

    б) выполнить посылку сигналов от «диспетчера» к «модели» и «регулятору» с подтверждением приема:

for(i=0; i< N; i++){
    kill(*p_reg, SIGUSR2); if(!gotcha2) pause(); gotcha2=0;
    for(j=0; j<M; j++){

      kill(*p_mod, SIGUSR1); 

      if(!gotcha1) pause(); gotcha1=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* end;
int i;
int* pid1;
int* pid2;
int* ch;
int j;
int* flag1;
int* flag2;

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

 *end=
0;
 j=
0;
 printf(
"\tGo!!!\n");

 
for(i=0;i<20;i++)
   {
   kill(*pid2, SIGUSR2);
   
if(!*flag2) pause();
   *flag2=
0;
   
for(j=0;j<5;j++)
     {
     kill(*pid1, SIGUSR1);
     
if(!*flag1) pause();
     *flag1=
0;
     fprintf(stderr,
"\t| %d\t| %d\t|\n",*c,*ch);
     }
   }

 kill(*pid1, SIGTERM);
 kill(*pid2, SIGTERM);
 
if(!shmdt(pmem)) fprintf(stderr,"\tMEMORY ALL RIGHT\n");
   
else fprintf(stderr,"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* pid1;
int* pid2;
int* end;
int* ch;
int* flag1;
int* flag2;

void obrab()
{
 *c+=
1;
 fprintf(stderr,
"%d\n",*c);
 *flag1=
1;
}
int main()
{
 dmem=shmget(mem,getpagesize(),IPC_CREAT|S_IRUSR|S_IWUSR);
 pmem=(
char*)shmat(dmem,0,0);
    pid1=(
int*)pmem;        *pid1=getpid();
    pid2=(
int*)(pmem+sizeof(int));
       c=(
int*)(pmem+sizeof(int)+sizeof(int));
     end=(
int*)(pmem+sizeof(int)+sizeof(int)+sizeof(int));
      ch=(
int*)(pmem+sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int));
   flag1=(
int*)(pmem+sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int));
   flag2=(
int*)(pmem+sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int));

 *c=
0;
 signal(SIGUSR1,obrab);
 printf(
"Peredatchic on start\n");

 
while(!*end) pause();

 
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 dmem;
char* pmem;
int* ch;
int* pid1;
int* pid2;
int* end;
int* c;
int* flag1;
int* flag2;

void obrab()
{
 (*ch)++;
 fprintf(stderr,
"%d\t%d\n",*c,*ch);
 *flag2=
1;
}

int main()
{
 dmem=shmget(mem,getpagesize(),IPC_CREAT|S_IRUSR|S_IWUSR);
 pmem=(
char*)shmat(dmem,0,0);
    pid1=(
int*)pmem;
    pid2=(
int*)(pmem+sizeof(int));      *pid2=getpid();
       c=(
int*)(pmem+sizeof(int)+sizeof(int));
     end=(
int*)(pmem+sizeof(int)+sizeof(int)+sizeof(int));
    ch=(
int*)(pmem+sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int));
   flag1=(
int*)(pmem+sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int));
   flag2=(
int*)(pmem+sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int));

 *ch=
0;
 signal(SIGUSR2, obrab);
 printf(
"Priemnic on start\n");

 
while(!*end) pause();

 
return 0;
}


 

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

13986. Глинка Михаил Иванович 29.91 KB
  Глинка Михаил Иванович Глинка Михаил Иванович 18041857 русский композитор. Первые музыкальные впечатления Глинки связаны с народной песней. Ещё в детстве приобщился к профессиональной музыке. Юные годы Глинки прошли в Петербурге. Благотворно отразились на формирован
13987. Теория и методика музыкального воспитания детей дошкольного возраста 786.25 KB
  Гогоберидзе А.Г. Теория и методика музыкального воспитания детей дошкольного возраста: Учеб. пособие для студ. высш. учеб. заведений /А. Г. Гогоберидзе В.А.Деркунская. М.: Издательский центр Академия 2005. 320 с. Оглавление ОТ АВТОРОВ Часть 1. ТЕОРЕТИЧЕСКИЕ ОСНОВЫ МУЗЫК...
13988. Урок. Как выбрать правильную гитару 73.5 KB
  Как выбрать правильную гитару У вас есть желание купить себе качественную гитару На первый взгляд это не проблема. Бытует мнение что тот у кого толстый бумажник имеет огромные преимущества. Узнавая все новые тонкости и мелочи в процессе выбора гитары самодовольн...
13989. Обзор музыкальной жизни Франции 19 века. Берлиоз. Франк 45 KB
  Лекция двенадцатая. Тема: Обзор музыкальной жизни Франции 19 века. Берлиоз. Франк. Начало 19 века. Первая половина. Главный жанр опера. В конце 17 века основан театр в Париже. В 30е годы складывается жанр большая опера. Джакомо Мейербер. Оперы: Робертдьявол Г
13990. История музыкальной культуры. Конспект лекций 1.32 MB
  Музыкальная культура Древнего мира История музыки это наука так как по методу она связана с логикой исторического процесса. Каждое музыкальное явление рассматривается ею в пространстве и во времени. Лишь с этих позиций мы можем объективно оценить значимость творчес
13991. Древнерусская музыкальная культура 40 KB
  3 Древнерусская музыкальная культура Развивалась она прежде всего как вокальная музыка. Истоки ее в народной русской песне. В народной песне отражалась вся жизнь народа труд быт вера и т.д.. Из самых древних песен известны колыбельные календарные песни...
13992. Особенности плана счетов бухгалтерского учета строительной организации 152.5 KB
  Строительство как отрасль экономики участвует в создании основных фондов для всех отраслей хозяйства. При изучении особенностей применения плана счетов в строительстве, следует иметь в виду, что принятие к бухгалтерскому учету возведенных основных средст
13993. Музыка. Что за прелесть эти сказки. Урок музыки в 4 классе 136.35 KB
  1. Урок музыки. 4 класс Раздел: День полный событий. Тема: Что за прелесть эти сказки Три чуда. Дидактическая цель: целенаправленно формировать способность воспринимать музыку как искусство выразительное по своей природе; расширить представления учащихся о свя...
13994. Вивчення нової пісні «Веселий музикант» слова Т.Волгіної, муз. А.Філіпенка, прослуховування пісні Українських троїстих музикантів та пісні «Ходить сон біля вікон» 16.15 KB
  Тема. Вивчення нової пісні Веселий музикант слова Т.Волгіної муз. А.Філіпенка прослуховування пісні Українських троїстих музикантів та пісні Ходить сон біля вікон. Мета. Вчити дітей словам нової пісні продовжувати роботу над формуванням вокально хорових навичо...