Назад

Пример выполнения лабораторной работы N9

Модель, реализуемая в данной работе следующая:

В программной модели действуют процессы двух типов. Процесс-Ганеша выполняет функции монитора для процессов-Слонов. Этот процесс существует в одном экземпляре. Процесс-Слон моделирует поведение одного Слона. Ганеша создает экземпляр такого процесса для каждого Слона в стаде. Структура информации, касающейся одного Слона, описана в файле elephant.h.

Ниже представлены укрупненные алгоритмы деятельности Ганеши и Слона. Приведем некоторые комментарии к этим схемам алгоритмов.

Реализация программной модели выполнена в кодовых модулях ganesha1.c и elephant1.c.

Программный модуль, реализующий деятельность Ганеши

  /**********************************************/
  /* Пример для работы 9                        */
  /**********************************************/
  /* ПОРОЖДЕНИЕ ПРОЦЕССОВ                       */
  /**********************************************/
  /* Монитор Слонов  - файл ganesha1.c          */
  /**********************************************/

  #include <stdio.h>
  #include <stdlib.h>
  #include <unistd.h>
  #include <sys/types.h>
  #include <sys/wait.h>
  #include <sys/time.h>
  #include <time.h>
  #include <signal.h>
  #include <sys/resource.h>

  #include "../common/ganesha.h"
  #include "../common/elephant.h"
  #include "../common/curtime.h"

  /*static*/ int ne;  /* параметр циклов */
  /*static*/ meleph mel[NE]; /* управляющая информация о Слонах */
  /*static*/ int cnt; /* число запущенных Слонов */

   /*static*/ char chld_name[]="./elephant1";
/********************************************************/

 main()
 {
       int stat;  /* состояние процесса при завершении */
        /* строки для символьного представления параметров */  
        char t1[PARAMSTR_LENGTH], t2[PARAMSTR_LENGTH],
             t3[PARAMSTR_LENGTH], t4[PARAMSTR_LENGTH];
        pid_t pw;   /* идентификатор процесса */
        char eee[ERRMES_LENGTH];   /* текст сообщения об ошибке */

        /* начало работы */          
        /* инициализация генератора случайных чисел */
	srand(time(NULL));
	 printf("%s - Начало работы\n",curtime());
        *t3=*t4=0;
        /* цикл по массиву Слонов */
        for (ne=0; ne<NE; ne++)
        {
                /* запись личных данных в управляющую информацию */
                mel[ne].el=&ee[ne];
                /* представление нестроковых данных в строковом виде */
                sprintf(t1,"%d",mel[ne].el->age);
                sprintf(t2,"%lf",mel[ne].el->weight); 

                /* порождение процесса */
		pw=fork();
                if (pw==0)
                {

                        /* для дочернего процесса - запуск программы-Слона */
                        /* личные данные передаются через параметры */
                        if (execl(chld_name, mel[ne].el->name, t1, t2, t3, t4, NULL)<0)
                        {  
                                /* если загрузка программы-Слона почему-либо не удалась,
                                печатается сообщение об ошибке, и процесс завершается */ 
                                perror(eee);
                                printf("%s\n",eee); exit(0);
                        }
                        /* если вызов execl выполнился успешно, то далее в 
                        дочернем процессе выполняется программа elephant1 */
                }

	         /* эта часть - только для процесса - Ганеши */
                /* заполнение управляющей информации о процессе  */
                /* состояние процесса пока что - не запущен */
                mel[ne].status=-1;
                /* установка случайной добавки к приоритету */
                mel[ne].prty=(int)(10.* rand()/RAND_MAX);  
                setpriority(PRIO_PROCESS,pw,mel[ne].prty);
                /* запоминание ID процесса-Слона */
                mel[ne].chpid=pw;
        }
        /* пауза, чтобы процессы успели загрузить Слонов */
        sleep(1);
	
	/* перебор запущенных процессов */
	for (cnt=ne=0; ne<NE; ne++)
        {
                /* проверка - не закончился ли процесс */
                pw=waitpid(mel[ne].chpid,&stat,WNOHANG);
                if (pw==mel[ne].chpid) 
                /* если процесс закончился, значит, запуск Слона не удался */
                        printf("Слон %s не запущен\n",mel[ne].el->name);
                else
                {
                        /* состояние процесса - запущен */
                        mel[ne].status=0;
                        /* подсчет запущенных Слонов */
                        cnt++;
                }
        }
	
	/* если счетчик запущенных 0 - завершение Ганеши */
        if (!cnt) exit(0);

        /* пауза монитора, Слоны в это время выполняются */
         sleep(5);
        printf("%s - ВРЕМЯ ОЖИДАНИЯ ИСТЕКЛО\n",curtime());

        /* перебор всех запущенных Слонов */
	for (ne=0; ne<NE; ne++)
        {
                /* если состояние процесса "не запущен", он не проверяется */
                if (mel[ne].status<0) continue;
                /* проверка завершения Слона с заданным ID, без ожидания завершения */
                pw=waitpid(mel[ne].chpid,&stat,WNOHANG);
                if (mel[ne].chpid==pw)
                {
                        /* если Слон завершился - сообщение о его успешном завершении */
                        printf("%s - Слон %s нормально завершился\n",
                        curtime(),mel[ne].el->name);
                }
                else
                {
                        /* если Слон не завершился, ему посылается сигнал KILL */
                        kill(mel[ne].chpid,SIGKILL);
                        /* ожидание завершения после сигнала */
                        waitpid(mel[ne].chpid,&stat,0);
                        /* сообщение о гибели */
                        printf("%s - Слон %s погиб\n",
                        curtime(),mel[ne].el->name,stat);
                }
        }
}

Программный модуль, реализующий деятельность одного Слона

  /**********************************************/
  /* Пример для работы 9                       */
  /**********************************************/
  /* Дочерний процесс,
                моделирующий поведение Слона    */
  /**********************************************/
  #include <stdio.h>
  #include <string.h>
  #include <unistd.h>
  #include <stdlib.h>
  #include <sys/types.h>
  #include <sys/time.h>
  #include <time.h>
  #include <sys/resource.h>

  /* структура личных данных Слона */
  #include "../common/elephant.h"

  #include "../common/wait.h"
  #include "../common/curtime.h"

  /*static*/ elephant this;  /* личные данные */
  /*static*/ int thisState;  /* состояние */

main(int an, char *av[])
{
        char msg[40];
        /* прием параметров */
        strcpy(this.name,av[0]);
        sscanf(av[1],"%d",&(this.age)); 
        sscanf(av[2],"%lf",&(this.weight));

        /* инициализация генератора случайных чисел */
        srand(time(NULL));
        /* состояние - 0 */
        thisState=0;

        /* сообщение о начале */
        printf("%s - Слон %s поиск начал, приоритет=%d\n",
        curtime(),this.name,getpriority(PRIO_PROCESS,getpid()));  
  
        /* время поиска воды - случайная величина, отчасти зависящая от возраста  */
        a1wait(10*(60-this.age));
        /* поиск окончен, состояние - 1 */
        thisState=1;

        /* сообщение об окончании поиска */
        printf("%s - Слон %s нашел воду\n",curtime(),this.name);

        /* время насыщения зависит от веса Слона */
        a0wait((int)(this.weight*30));

        /* сообщение об окончании водопоя */
        printf("%s - Слон %s напился\n",curtime(),this.name);

        /* завершение процесса */
         exit(0);
}

Для дальнейших применений мы ввели параметры вызова дочернего процесса t3 и t4, в данном примере их значения - пустые строки.

Ниже приводится пример выполнения модели

  13:12:08.853 - Начало работы
  13:12:08.897 - Слон Assam поиск начал, приоритет=2
  13:12:08.966 - Слон Aun поиск начал, приоритет=5
  13:12:09.006 - Слон Hathy поиск начал, приоритет=1
  13:12:09.075 - Слон BakZap поиск начал, приоритет=5  
  13:12:09.078 - Слон BakZap нашел воду
  13:12:09.125 - Слон Tandy поиск начал, приоритет=7
  13:12:09.165 - Слон Maya поиск начал, приоритет=7
  13:12:09.236 - Слон Kitty поиск начал, приоритет=2
  13:12:09.275 - Слон Hao поиск начал, приоритет=7
  13:12:10.031 - Слон Hathy нашел воду
  13:12:10.359 - Слон Maya нашел воду
  13:12:12.561 - Слон Kitty нашел воду
  13:12:12.734 - Слон Hao нашел воду
  13:12:14.516 - Слон Tandy нашел воду
  13:12:22.921 - Слон Tandy напился
  13:12:24.911 - Слон Kitty напился
  13:12:25.205 - Слон Assam нашел воду
  13:12:28.193 - Слон Hao напился
  13:12:29.873 - Слон BakZap напился
  13:12:30.091 - Слон Maya напился
  13:12:32.486 - Слон Hathy напился
  13:12:35.204 - Слон Assam напился
  13:12:35.890 - ВРЕМЯ ОЖИДАНИЯ ИСТЕКЛО
  13:12:35.890 - Слон Tandy нормально завершился
  13:12:35.891 - Слон Aun погиб
  13:12:35.891 - Слон Assam нормально завершился
  13:12:35.892 - Слон Maya нормально завершился
  13:12:35.892 - Слон BakZap нормально завершился
  13:12:35.892 - Слон Hao нормально завершился
  13:12:35.892 - Слон Hathy нормально завершился
  13:12:35.892 - Слон Kitty нормально завершился


Назад