Сидоров А.О / ос7
.docx
Министерство образования Республики Беларусь
Белорусский Национальный Технический Университет
Факультет информационных технологий и робототехники
Кафедра «Программное обеспечение вычислительной техники
и автоматизированных систем»
Отчёт
по лабораторной работе № 7
по дисциплине «Операционные системы»
тема: «Основы многозадачности в Linux.
Процессы в Linux»
Исполнитель: |
|
студент группы 10702112 Сидоров А.О. |
Преподаватель: |
|
Радкевич А.С. |
2013-2014 учебный год
ЛАБОРАТОРНАЯ РАБОТА № 7
Основы многозадачности в Linux.
Процессы в Linux
Цель работы
Изучить фундаментальные концепции многозадачности, а также научиться создавать многозадачные приложения в рабочей среде ОС Linux путём порождения и управления процессами.
Требования
1) Разработать модульное консольное приложение на С/С++ согласно варианту задания. Для компиляции, компоновки и выполнения программы использовать утилиту make.
2) Для каждой бригады необходимо выполнить задание A полностью и по одному варианту задания B на человека (к примеру, если в бригаде 2 человека,то необходимо выполнить 2 задания, если в бригаде 3 человека – 3 задания и т.д.).
Индивидуальное задание:
Задание A
Приложение, разработанное при выполнении лабораторной работы No 2, запустить как дочерний процесс. Родитель должен передавать соответствующие данные для работы дочернего процесса, получать результат выполнения и выводить его в терминал и/или в файл. Предусмотреть возможность установки приоритета для соответствующего запускаемого дочернего процесса, а также привязку его выполнения на конкретном ядре процессора.
Задание B
Необходимо написать программу, которая выводит список выполняемых текущим пользователем процессов, а также процессов, выполняемых другими пользователями и системных процессов (или всех процессов в системе).
Ход выполнения лабораторной работы:
-
В текстовом редакторе gedit набрал исходный код решения задания на языке программирования С++ и сохранил исходник. Программа состоит из следующих файлов:
-
function.h – файл заголовка, в котором описаны прототипы функций;
-
parent.cc - файл,который запускает дочерний процесс;
-
function.cc – файл реализации функций;
-
test.cc – файл, в котором описана главная функция программы main;
-
Запустил терминал Linux и с помощью команды cd перешёл в папку местонахождения исходных кодов программы.
-
Для компиляции программы использовал утилиту make и созданный make-файл.
Результаты выполнения лабораторной работы:
Рисунок 1 — Использование утилиты make
Рисунок 2 — Выполнение программы
Что я освоил в процессе выполнения лабораторной работы:
-
Изучил основные системный вызовы для работы с процессами:
fork() - cистемный вызов, создающий новый процесс (потомок), который является практически полной копией процесса-родителя, выполняющего этот вызов.
exec() - заменяет пользовательский контекст текущего процесса на содержимое некоторого исполняемого файла и устанавливает начальные значения регистров процессора
setpriority() - устанавливает приоритет процесса
sched_setaffinity() - устанавливает процессорную маску соответствия для процесса с идентификатором pid
Выводы:
-
Основными системными вызовами для работы с процессами: fork(),семейство exec(),nice(),setpriority(),sched_setaffinity.
ПРИЛОЖЕНИЕ A
Листинг исходного кода программы
Файл functions.h
#ifndef function_H
#define function_H
int poisk(char *s);
int l(char *s,char str[]);
#endif
Файл functions.cc
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <time.h>
#include <stdio.h>
#include "function.h"
using namespace std;
int poisk(char *s){
int cnt=0,f;
for(int i=0;i<strlen(s);i++){
f=1;
for(int j=0;j<strlen(s);j++){
if(i!=j&&s[i]==s[j])
f=0;
}
if(f)
++cnt;
}
return cnt;
}
int l(char *s,char str[])
{
int m=1;
s=strtok(str," ,.!?()");
while(s){
if (poisk(s)==strlen(s)&&m==1){
m=0;
printf("Slovo: ");
fflush(stdout);
printf("%s",s);
fflush(stdout);
}
s=strtok(NULL," ,.!?()");
}
fclose(stdout);
return 0;
}
Файл test.cc
#include <stdio.h>
#include <iostream>
#include "function.h"
using namespace std;
int main(int size,char **argv)
{
l(*argv,argv[1]);
return 0;
}
Файл Makefile
test: test.o function.o
g++ test.o function.o -o test
parent: parent.o
g++ parent.o -o parent
parent.o: parent.cc
g++ -c parent.cc
test.o: test.cc function.h
g++ -c test.cc
function.o: function.cc function.h
g++ -c function.cc
Файл parent.cc
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <errno.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <sys/resource.h>
#include <sched.h>
using namespace std;
char vivod()
{
char ch;
cout<<"Хотите изменить приоритет?\n";
cout<<"1-Да\n";
cout<<"2-Нет\n";
cin.ignore();
ch = getchar();
return ch;
}
char vivod2()
{
char ch;
cout<<"\nВывести результат в файл?\n";
cout<<"1-Да\n";
cout<<"2-Нет\n";
cin.ignore();
ch = getchar();
return ch;
}
char vivod3()
{
int ch;
cout<<"Введите номер ядра(1-8): \n";
cin>>ch;
return ch;
}
int main(int size,char **argv)
{
int len;
char ch,str[128];
int status,priority,ch1,pipedes[2];
cpu_set_t my_set;
CPU_ZERO(&my_set);
ch1=vivod3();
CPU_SET(ch1, &my_set);
pid_t pid;
pipe(pipedes);
pid=fork();
if(pid==-1){
perror("Error:");
exit(1); }
else if (pid==0){
if(size>1)
{
sched_setaffinity(pid, sizeof(cpu_set_t), &my_set);
ch=vivod();
if (ch=='1') {
cout<<"Введите приоритет([-20;19]): ";
cin>>priority;
cout<<"\n";
setpriority(PRIO_PROCESS,0,priority);}
close(pipedes[0]);
dup2(pipedes[1],1);
execl("test","",argv[1],NULL);
exit(0);
}
else
{
ch=vivod();
if (ch=='1') {
cout<<"Введите приоритет([-20;19]): ";
cin>>priority;
setpriority(PRIO_PROCESS,0,priority);}
sched_setaffinity(pid, sizeof(cpu_set_t), &my_set);
cout<<"\nString: ";
cin.ignore();
fgets(str,128,stdin);
close(pipedes[0]);
dup2(pipedes[1],1);
execl("test","",str,NULL);
exit(0);
}
} else
{
char buf[128];
read(pipedes[0],buf,sizeof(buf));
cout<<buf;
ch=vivod2();
if (ch=='1')
{
ofstream out;
out.open("Phone.out");
out<<buf;
out.close();
}
}
return 0;
}
ПРИЛОЖЕНИЕ B
Листинг исходного кода программы
Файл test.cc
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
using namespace std;
void vivod(){
cout<<"1-Вывести процессы текущего пользователя\n";
cout<<"2-Вывести процессы другого пользователя\n";
cout<<"3-Вывести все процессы\n";}
int main(int size,char **argv)
{
char ch,*p,str1[128],str2[128];
char str[128]="ps u -u ";
vivod();
do
{
ch = getchar();
switch(ch)
{
case '1' :
p=getenv("USER");
strcpy(str1,str);
strcat(str1,p);
system(str1);vivod();break;
case '2' :
cout<<"Введите имя нужного пользователя: ";
cin.ignore();
fgets(str2,128,stdin);
strcpy(str1,str);
strcat(str1,str2);
system(str1);vivod();break;
case '3' :
system("ps u -A");vivod();break;
}
}
while(ch!='0');
return 0;
}