Добавил:
БГУИР ПОИТ Дистанционное Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ИПР2_ОС.docx
Скачиваний:
10
Добавлен:
31.01.2022
Размер:
918.34 Кб
Скачать

БЕЛОРУССКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ

ИНФОРМАТИКИ И РАДИОЭЛЕКТРОНИКИ

Кафедра программного обеспечения информационных технологий

Факультет ФКСиС

Специальность ПОИТ

Индивидуальная практическая работа №2

по дисциплине «Операционные системы и системное программирование.

Часть 1»

Выполнил студент: Бордон Е.С.

группа 991051

Зачетная книжка № 99105004

Минск 2021

Расчёт выбора варианта:

Номер паспорта :

Тк в первой таблице первого задания всего 16 вариантов

Значения табл.1 по заданию mod 16 = 3

Тк во второй таблице первого задания всего 14 вариантов

Значения табл.2 по заданию 1: mod 14 = 11

Во втором задании второй работы всего 19 вариантов:

Вариант задания 2: mod 19 = 12

Задание 1:

Создать дерево процессов согласно варианта индивидуального задания.

Процессы непрерывно обмениваются сигналами согласно табл. 2. Запись в таблице 1 вида: 1-> (2,3,4,5) означает, что исходный процесс 0 создаёт дочерний процесс 1, который, в свою очередь, создаёт дочерние процессы 2,3,4,5. Запись в таблице 2 вида: 1-> (2,3,4) SIGUSR1 означает, что процесс 1 посылает дочерним процессам 2,3,4 одновременно (т.е. за один вызов kill ()) сигнал SIGUSR1. После передачи 101–го по счету сигнала SIGUSR родительский процесс посылает сыновьям сигнал SIGTERM и ожидает завершения всех сыновей, после чего завершается. Сыновья, получив сигнал SIGTERM завершают работу с выводом на консоль сообщения вида:

Pid ppid завершил работу после X-го сигналаSIGUSR1 и Y-го сигналаSIGUSR2

где X, Y – количество посланных за все время работы данным сыном сигналов SIGUSR1 и SIGUSR2

Каждый процесс в процессе работы выводит на консоль информацию в следующем виде:

Npidppid послал/получил USR1/USR2 текущее время (мксек)

где N-номер сына по табл. 1

Дерево процессов:

1->(2,3) 2->(4,5) 5->6 6->(7,8)

Последовательность обмена сигналами:

1->(8,7,6,5)SIGUSR1 8->3 SIGUSR17->3 SIGUSR2

6->3 SIGUSR1 5->3 SIGUSR1 3->2 SIGUSR2 2->1 SIGUSR2

Решение:

#include <stdio.h>

#include <unistd.h>

#include <signal.h>

#include <stdlib.h>

#include <string.h>

#include <time.h>

#include <errno.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <sys/time.h>

#include <sys/wait.h>

#include "sys/ipc.h"

#include <libgen.h>

#include "sys/shm.h"

#define TREE_COUNT 8

#define PERM S_IRUSR|S_IWUSR

char *exe_name;

int sig1 = 0, sig2 = 0;

pid_t gID, ppID;

struct sigaction sact;

size_t m_size;

key_t shmid_Tree;

pid_t *process_ID;

struct timeval curr_Time, start_Time, elapsed_Time;

void treeDo(int index);

void forestDo(int pID);

int getOrdForTree(int pid) {

for (int i = TREE_COUNT;; i--) if (process_ID[i] == pid) return i;

return -1;

}

void treeDo(int index) {

if (fork() == 0) {

process_ID = shmat(shmid_Tree, 0, 0);

process_ID[index] = getpid();

forestDo(process_ID[index]);

}

}

void forestDo(int pID) {

gID = getpgid(pID);

ppID = getppid();

int treeOrd = getOrdForTree(pID);

switch(treeOrd) {

case 1:

treeDo(2);

treeDo(3);

break;

case 2:

treeDo(4);

treeDo(5);

break;

case 3:

break;

case 4:

break;

case 5:

treeDo(6);

break;

case 6:

treeDo(7);

treeDo(8);

break;

case 7:

break;

case 8:

break;

default:

break;

}

while (1) pause();

}

int gettime()

{

gettimeofday(&curr_Time, NULL);

timersub(&curr_Time, &start_Time, &elapsed_Time);

return elapsed_Time.tv_usec/1000;

}

void manageTree1() {

sig1++;

if (sig1 + sig2 > 100) {

kill(process_ID[8], SIGTERM);

}

else {

printf("%d %d %d put SIGUSR1 %3d\n", 1, getpid(), getppid(), gettime());

kill(-getpgid(process_ID[2]), SIGUSR1);

}

}

void manageTree2() {

sig2++;

printf("%d %d %d put SIGUSR2 %3d\n", 2, getpid(), getppid(), gettime());

kill(process_ID[1], SIGUSR2);

}

void manageTree3() {

sig2++;

printf("%d %d %d put SIGUSR2 %3d\n", 3, getpid(), getppid(), gettime());

kill(process_ID[2], SIGUSR2);

}

void manageTree4() {

sig2++;

}

void manageTree5() {

sig1++;

printf("%d %d %d put SIGUSR1 %3d\n", 5, getpid(), getppid(), gettime());

kill(process_ID[3], SIGUSR1);

}

void manageTree6() {

sig1++;

printf("%d %d %d put SIGUSR1 %3d\n", 6, getpid(), getppid(), gettime());

kill(process_ID[3], SIGUSR1);

}

void manageTree7() {

sig1++;

printf("%d %d %d put SIGUSR2 %3d\n", 7, getpid(), getppid(), gettime());

kill(process_ID[3], SIGUSR2);

}

void manageTree8() {

sig1++;

printf("%d %d %d put SIGUSR1 %3d\n", 8, getpid(), getppid(), gettime());

kill(process_ID[3], SIGUSR1);

}

static void manage (int signal) {

int timer = gettime();

int tree_Num = getOrdForTree(getpid());

if (signal == SIGTERM) {

switch (tree_Num) {

case 1: waitpid(process_ID[1], 0, 0);

printf("%d %d %d done SIGUSR1: %3d, SIGUSR2: %3d\n", tree_Num, getpid(), ppID, sig1, sig2);

kill(process_ID[0],SIGTERM);

exit(EXIT_SUCCESS);

break;

case 0:

wait(NULL);

exit(EXIT_SUCCESS);

break;

default: // 2,3,4,5,6,7,8

printf("%d %d %d done SIGUSR1: %3d, SIGUSR2: %3d\n", tree_Num, getpid(), ppID, sig1, sig2);

kill(process_ID[tree_Num-1],SIGTERM);

exit(EXIT_SUCCESS);

break;

}

return;

}

if (signal == SIGUSR1) {

switch (tree_Num) {

case 5:

printf("%d %d %d get SIGUSR1 %3i\n", 5, getpid(), getppid(), timer);

manageTree5();

break;

case 6:

printf("%d %d %d get SIGUSR1 %3i\n", 6, getpid(), getppid(), timer);

manageTree6();

break;

case 7:

printf("%d %d %d get SIGUSR1 %3i\n", 7, getpid(), getppid(), timer);

manageTree7();

break;

case 8:

printf("%d %d %d get SIGUSR1 %3i\n", 8, getpid(), getppid(), timer);

manageTree8();

break;

}

return;

}

if (signal == SIGUSR2) {

switch (tree_Num) {

case 1:

printf("%d %d %d get SIGUSR2 %3i\n", 1, getpid(), getppid(), timer);

manageTree1();

break;

case 2:

printf("%d %d %d get SIGUSR2 %3i\n", 2, getpid(), getppid(), timer);

manageTree2();

break;

case 3:

printf("%d %d %d get SIGUSR2 %3i\n", 3, getpid(), getppid(), timer);

manageTree3();

break;

}

return;

}

return;

}

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

exe_name = basename(argv[0]);

m_size = (TREE_COUNT+1) * sizeof(pid_t);

if ((shmid_Tree = shmget(IPC_PRIVATE, m_size , PERM)) == -1 ) {

perror(exe_name);

exit(EXIT_FAILURE);

}

process_ID = shmat(shmid_Tree, 0, 0);

memset(process_ID, 0, m_size);

process_ID[0] = getpid();

sact.sa_handler = manage;

sigemptyset(&sact.sa_mask);

sact.sa_flags = 0;

if (sigaction(SIGUSR1, &sact, 0) != 0) perror(exe_name);

if (sigaction(SIGUSR2, &sact, 0) != 0) perror(exe_name);

if (sigaction(SIGTERM, &sact, 0) != 0) perror(exe_name);

if (fork() == 0) {

process_ID[1] = getpid();

forestDo(process_ID[1]);

} else {

process_ID[1] = process_ID[0]+1;

}

if (setpgid(process_ID[5], process_ID[2]) != 0) perror(exe_name);

if (setpgid(process_ID[6], process_ID[2]) != 0) perror(exe_name);

if (setpgid(process_ID[7], process_ID[2]) != 0) perror(exe_name);

if (setpgid(process_ID[8], process_ID[2]) != 0) perror(exe_name);

int flag = 0;

while (!flag) {

int temp = -1;

for (int i = 1; i <= TREE_COUNT; i++) {

temp = temp && process_ID[i];

}

flag = temp;

}

gettimeofday(&start_Time, NULL);

if (kill(process_ID[1], SIGUSR2) != 0) perror(exe_name);

pid_t wpid;

int status;

while (1) pause();

}

Результаты работы программы:

Рис1. Результат работы программы

Рис2. Результат работы программы

Задание 2:

Для заданного каталога (аргумент 1 командной строки) и всех его

подкаталогов вывести в заданный файл (аргумент 2 командной строки) и на

консоль имена файлов, их размер и дату создания, удовлетворяющих заданным

условиям: 1 – размер файла находится в заданных пределах от N1 до N2

(N1,N2задаются в аргументах командной строки), 2 – дата создания находится в заданных пределах от M1 до M2 (M1,M2задаются в аргументах командной

строки).Процедура поиска для каждого подкаталога должна запускаться в

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

подкаталоге. Число запущенных процессов в любой момент времени не должно

превышать N (вводится пользователем). Проверить работу программы для каталога /usr/ размер31000 31500 дата с 01.01.1970 по текущую датуN=6. Для

взаимодействия процессов использовать сигналы. То же что и в п.3, но вместо процессов использовать потоки.

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