lab6
.docxМИНОБРНАУКИ РОССИИ
Санкт-Петербургский государственный
электротехнический университет
«ЛЭТИ» им. В.И. Ульянова (Ленина)
Кафедра вычислительной техники
Отчет по лабораторной работе №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