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;
}


 

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

62036. Урок по подвижным играм 40.79 KB
  Прыгают сначала игроки одной команды затем другой. Правила игры: 1 во время перебежки мяч можно только отбивать как в волейболе а не перебрасывать; 2 если мяч во время передачи упал игрок уронивший мяч должен поднять его и продолжать игру дальше...
62037. Композиція у декоративному мистецтві. Створення ескізу писанки 25.39 KB
  Сьогодні ми з вами зробимо віртуальну подорож щоб дізнатися багато нового та цікавого Слайд 1. Отже перша зупинка Історія писанки слайд 2. Писанки це найпоширеніший вид декоративно-прикладного мистецтва це своєрідний мініатюрний живопис наповнений ритуальним значенням...
62038. Повторение передачи мяча сверху 2-мя руками и прием снизу 2-мя руками 18.02 KB
  Бег с высоким подниманием бедра лицом и спиной вперед с захлестыванием голени лицом и спиной вперед бег левым и правым приставным шагом. Стоя спиной друг к другу мяч вверху; 1. стоя спиной друг к другу мяч верху. стоя спиной друг к другу мяч на пояснице руки в замок.
62040. Food 21.23 KB
  Цілі уроку: Практична: вчити використовувати нові лексичні одиниці на понадфразовому рівні в усній та письмовій формах тренувати учнів у складанні монологічного висловлювання за темою уроку; формувати вміння давати відповіді на поставлені запитання; розвивати навички читання письма.
62042. Изображение головы человека в пространстве 25.47 KB
  Познакомить учащихся с закономерностями в конструкции головы человека пропорциями лица человека. Презентация; Зрительный ряд презентация примеры работ Модель гипсовой головы...
62043. Гигиена девушки. Косметика 31.36 KB
  Учащиеся должны знать: как ухаживать за телом кожей волосами; как правильно держать осанку и походку; тип кожи тип волос; Учащиеся должны уметь: ухаживать за телом кожей волосами; определять тип кожи; определять тип волос и ухаживать за ними...
62044. Грибы съедобные и несъедобные. Правила сбора грибов 23.02 KB
  Цель: учить распознавать грибы формировать представление о грибах как об особом царстве живой природы; познакомить с видами грибов; учить осторожности при сборе грибов объяснить чем грозят последствия неправильного сбора и употребления грибов...