2268

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

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

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

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

Русский

2013-01-06

56 KB

13 чел.

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

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

Кафедра АМТ

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

Лабораторная работа №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;
}


 

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

20932. Модель технологического процесса в пакете программ Верти 2.79 MB
  Цели и задачи: Изучить методику управления классами модели атрибутами классов управления функциями управления связями между классами и управления фильтрами в пакете программ . После занятия студент должен: Знать: Методику управления классами модели атрибутами классов управления функциями управления связями между классами и управления фильтрами в пакете программ ВертикальТехнология.
20933. Администрирование в приложении «Система трудового нормирования по укрупненым нормам времени» 4.72 MB
  Уметь: Настраивать новые карты трудового нормирования редактировать справочник критериев поиска нормировочных карт настраивать справочные коэффициенты нормировочных карт. Проработать теоретический материал по теме:: администрирование в приложении Система трудового нормирования по укрупненым нормам времени [3] глава 16 [2] лекция №3 Индивидуальное задание: Настроить новую карту трудового нормирования. Система трудового нормирования по...
20934. Установка и настройка системы Вертикаль-Справочник 4.65 MB
  После занятия студент должен: Знать: Порядок установки и настройки Вертикаль Справочника подготовки системы работе. Проработать теоретический материал по теме: Настройка параметров в пакете программ Вертикаль Технология. [1] глава 1 [2] лекция №5 Индивидуальное задание: Настроить доступ индивидуальных пользователей и группы пользователей к ВертикальСправочнику.
20935. Методы работы с базой данных Вертикаль-Справочник 4 MB
  Цели и задачи: Изучить основные методы работы с базой данных ВертикальСправочник. После занятия студент должен: Знать: Основные методы работы с базой данных ВертикальСправочник Уметь: Загружать базы данных в рабочее поле системы; осуществлять поиск информации в базе данных; создавать таблицы типоразмеров; сортировать и заменять данные в таблицах. Для выполнения лабораторной работы необходимо: Проработать теоретический материал по теме: Методы работы с базой данных ВертикальСправочник.
20936. Приложение «Расчет режимов резания» 786 KB
  Уметь: Настроить текущий блок расчета режимов резанья настроить расчет параметров обработки параметров режущего инструмента параметров станка. [1] глава 13 [2] лекция №4 Индивидуальное задание: Настроить текущий блок расчета режимов резанья настроить расчет параметров обработки параметров режущего инструмента параметров станка. Как осуществляется настройка расчета параметров обработки 3. Назначение приложения Приложение Расчет режимов резания...
20937. Модификация структур баз данных, формирование SQL- запро-сов и VB-функций, настройка фильтрации данных в системе Вертикаль-Справочник 4.43 MB
  Цели и задачи: Изучить методику модификации структур баз данных порядок формирование SQL запросов и VBфункций настройку фильтрации данных в системе ВертикальСправочник. После занятия студент должен: Знать: Как отредактировать структуру баз данных и состав таблиц сформировать пользовательские SQLзапросы как настроить фильтрацию данных по различным признакам . Уметь: Подключить несколько таблиц к одному уровню сформировать пользовательские VBфункции настроить фильтрацию данных по различным признакам .
20938. Защита данных, организация вычислений по формулам, синхронизация серверных баз данных в системе Вертикаль-Справочник 4.58 MB
  Цели и задачи: Изучить методы защиты данных организацию вычислений по формулам синхронизацию серверных баз данных в системе ВертикальСправочник. После занятия студент должен: Знать: Методы защиты данных организацию вычислений по формулам синхронизацию серверных баз данных в системе ВертикальСправочник. Проработать теоретический материал по теме: Проектирование реляционной структуры пользовательских баз данных ВертикальСправочник.
20939. Проектирование объектной структуры пользовательских баз данных в системе Вертикаль-Справочник 2.93 MB
  После занятия студент должен: Знать: Принципы в структуре баз данных системы порядок регистрации нового класса объектов порядок настройки связи между объектами. Уметь: Выполнить регистрацию нового класса объектов настроить связи между объектами редактировать атрибуты связей объектов.3 [2] лекция №11 Индивидуальное задание: Выполнить регистрацию нового класса объектов настроить связи между объектами редактировать атрибуты связей объектов. Какой порядок регистрации нового класса объектов 3.
20940. Проектирование реляционной структуры пользовательских баз данных Вертикаль-Справочник 4.45 MB
  Цели и задачи: Изучить реляционные и объектные составляющие баз данных каталог баз данных редактор навигационных схем. После занятия студент должен: Знать: Общие сведения о каталоге баз данных как проектируются навигационные системы . Уметь: Заригистрировать новые базы данных настроить атрибуты связей объектов навигационной схемы.