Добавил:
Кафедра ВТ Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

lab6

.docx
Скачиваний:
9
Добавлен:
02.01.2023
Размер:
472.61 Кб
Скачать

МИНОБРНАУКИ РОССИИ

Санкт-Петербургский государственный

электротехнический университет

«ЛЭТИ» им. В.И. Ульянова (Ленина)

Кафедра вычислительной техники

Отчет по лабораторной работе №6

по дисциплине «Организация процессов и программирование в среде Linux»

Студент гр.

Преподаватель

Разумовский Г.В.

Тема: Организация периодических процессов

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

Задание:

Написать периодическую программу, в которой период запуска и количество запусков должны задаваться в качестве ее параметров. При каждом очередном запуске программа должна порождать новый процесс, который выводить на экран свой идентификатор, дату и время старта. Программа и ее дочерний процесс должны быть заблокированы от завершения при нажатии клавиши Ctrl/z. После завершения дочернего процесса программа должна вывести на экран информацию о времени своей работы и дочернего процесса.

Программа main.cpp

#include <iostream>

#include <signal.h>

#include <sys/wait.h>

#include <sys/time.h>

#include <unistd.h>

//set - маска сигналов ("множество")

using namespace std;

void processFunction (int local_int); // повторяющаяся функция

float finalTime (float local_start_time); // подсчет окончательного времени

int main(int argc, char *argv[])

{

    int number_period = atoi(argv[1]); // время на 1 запуск

    int number_launch = atoi(argv[2]); // кол-во запусков

    float start_time; // начало отсчета процесса-родителя

    struct itimerval value; // новое значение таймера

    struct itimerval old_value; // текущее значение таймера

    struct sigaction sigact; //структура, в которой описывается реакция на сигнал

    sigact.sa_handler = processFunction; // установка функции

    sigemptyset(&sigact.sa_mask); // очистка маски от всех сигналов

   

    sigaddset(&sigact.sa_mask, SIGTSTP); // добавление сигнала SIGTSTP к маске

    //функция используется для изменения сигнальной маски текущего процесса

    sigprocmask(SIG_BLOCK, &sigact.sa_mask, NULL); // блокировка сигнала SIGTSTP (чтобы при Ctrl+Z ничего не происходило)

    sigact.sa_flags = 0; // отсутствие флагов

    sigaction(SIGALRM, &sigact, NULL); // определяет текущую реакцию на сигнал SIGALRM

    //для того чтобы у родительского процесса

    //изначально был какой-то запас времени после начала выполнения функции    

    value.it_value.tv_sec = 0;

    value.it_value.tv_usec = 10; //микросекунды

   

    // установка нового интервала

    value.it_interval.tv_sec = number_period;

    value.it_interval.tv_usec = 0;

    //время ожидания между вызовами функций

   

    setitimer(ITIMER_REAL, &value, &old_value); // ITIMER_REAL означает таймер уменьшается постоянно

    //&value - начальные установки, в &old_value - возвр. текущие значения

    //после истечения времени будет послан сигнал SIGALRM

   

    for (int i = 0; i < number_launch; i++)

    {

        start_time = (float)clock() / CLOCKS_PER_SEC;

        pause(); // ожидание сигнала SIGALRM

        cout << "Parent process' work time (seconds): " << finalTime(start_time) << "\n\n";

    }

    return 0;

}

void processFunction (int local_int) // повторяющийся процесс

{

    int local_status; // статус для "waitpid" функции

    float local_start_time; // начало отсчета времени работы дочернего процесса

    pid_t local_pid = fork(); // создание дочернего процесса

    if (local_pid == 0) // если родительский процесс создан

    {

        time_t local_seconds = time (NULL); // //кол-во секунд после запуска дочернего процесса

        sigset_t local_set; // маска из одного сигнала

        struct tm* local_time = localtime (&local_seconds); // время начала работы родителя

        local_start_time = (float)clock() / CLOCKS_PER_SEC; // время начала работы дочернего процесса

       

        sigemptyset(&local_set); // установка пустого сигнала

       

        cout << "Child process' PID: " << getpid() << "\n"; // получение ID дочернего процесса

        cout << "Parent process' work start time: " << asctime(local_time);

        sigaddset(&local_set, SIGTSTP); // добавление сигнала SIGTSTP к текущему процессу //то же самое, что и на 30-31 строках

        sigprocmask(SIG_BLOCK, &local_set, NULL);

       

        exit(EXIT_SUCCESS);

    }

    else

    {

        waitpid(local_pid, &local_status, 0); // подождем, пока дочерний процесс завершит свою работу (по local_pid)

        cout << "Child process' work time (seconds): " << finalTime(local_start_time) << "\n";

    }

}

float finalTime (float local_start_time)

{

    return (float)clock() / CLOCKS_PER_SEC - local_start_time;

}

Вывод программы

Санкт-Петербург

2022

Соседние файлы в предмете Программирование в среде Linux