NetNado
  Найти на сайте:

Учащимся

Учителям



Отчет по лабораторной работе №4 по дисциплине «Операционные системы»



Национальный исследовательский

Томский Политехнический университет

Институт – Кибернетический Центр

Направление – Информатика и вычислительная техника

Кафедра – Оптимизации систем управления

«ПРАКТИЧЕСКОЕ ЗНАКОМСТВО С ПРОЦЕССАМИ,
ПЕРЕДАЧЕЙ ДАННЫХ МЕЖДУ ПРОЦЕССАМИ
И ИХ СИНХРОНИЗАЦИЕЙ»

Отчет по лабораторной работе № 4
по дисциплине «Операционные системы»

Выполнил

Студент группы 8в83 ___________ А.В. Колчанов


Проверил ___________ Д. В. Сидоров


Томск 2011
Цель работы

Практическое знакомство с объектом процесс, основными механизмами передачи данных между процессами, а также синхронизацией взаимодействующих процессов в ОС Unix.

Задание

Изучить базовые возможности оболочки bash ОС Unix по управлению процессами (заданиями). Разработать приложения реализующие схему «клиент-сервер» с использованием средств межпроцессорного взаимодействия: семафоров, разделяемой памяти, программных каналов и одной очереди сообщений.

Выполнение работы

1. Программа-клиент создаёт случайную последовательность случайной длины, программа-сервер должна определить количество чисел и их сумму (чисел не больше 100, все положительные и не превышают 100). Использована разделяемая память с синхронизацией с помощью семафоров.
#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include
#define FLAGS (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)

#define MYKEY 1234L

#define MKEY 1235L
using namespace std;
union st

{

int val;

struct semid_ds *buf;

unsigned short *array;

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

{

pid_t pid; // идентификатор дочернего процесса
union st arg;

struct sembuf pbuf;

printf("Родитель : создание семафора\n");

int semid = semget( MYKEY, 1, FLAGS|IPC_CREAT);

arg.val = 2;

semctl( semid, 0, SETVAL, arg);

printf("Родитель : инициализация общей памяти \n");

// инициализация общей памяти

int mid = shmget( MKEY, 100, FLAGS|IPC_CREAT);

short *ptr = (short *)shmat( mid, NULL, 0);

printf("Родитель : инициализация успешно завершена \n");

if (( pid =fork()) ==0) //дочерний процесс

{

printf(" Потомок : процесс-поток создан\n");

int ch_semid = semget( MYKEY, 1, FLAGS|IPC_EXCL);

printf(" Потомок : открытие семафора... \n");

// инициализация общей памяти

printf(" Потомок : инициализация общей памяти\n");

int ch_mid = shmget( MKEY, 100, FLAGS|IPC_EXCL);

short *ch_ptr = (short *)shmat( ch_mid, NULL, 0);

struct sembuf ch_buf;

ch_buf.sem_num = ch_buf.sem_flg = 0;

ch_buf.sem_op = -1;

semop( ch_semid, &ch;_buf, 1);

printf(" Потомок : запись в общую память\n");

// запись в общую память

int count= 20;

int i;

int sum = 0;

for ( i=0; i<100; i++) ch_ptr[i]=0;

for ( i=0; i
{

ch_ptr[i] =20;

sum += ch_ptr[i];

}

printf(" Потомок : записано число %d \n", sum);

sleep(3);

semop( ch_semid, &ch;_buf, 1); // запуск основной проги

//уход в режим ожидания

printf(" Потомок : ожидание ответа от родителя\n");

union st ch_arg;

ch_arg.val = 1;

semctl( ch_semid, 0, SETVAL, ch_arg);

ch_buf.sem_op = ch_buf.sem_flg = ch_buf.sem_num =0;

semop( ch_semid, &ch;_buf, 1);

printf(" Потомок : получен ответ от родителя ");

if ( *ch_ptr == count) printf("ОК"); else printf("Ошибка");

printf("\n Потомок : я уничтожен \n");

exit(0);

}
printf("Родитель : ожидание открытия семафора...\n");

pbuf.sem_num = pbuf.sem_flg = pbuf.sem_op = 0;

semop( semid, &pbuf;, 1); //

printf("Родитель : считывание с общей памяти \n");

// считывание с общей памяти

int j=0;
int psum =0;

while (ptr[j]>0) psum+=ptr[j++];

*ptr = j; //ответ для дочернего процесса

printf("Родитель : число равно %d \n", psum);

sleep(2);

printf("Родитель : начато открытие дочернего потока\n");

pbuf.sem_num = pbuf.sem_flg = 0;

pbuf.sem_op = -1;

semop( semid, &pbuf;, 1);

printf("Родитель : дочерний процесс разблокирован\n");

printf("Родитель : ожидание завершения потомка\n");

waitpid( pid, NULL, 0);

printf("Родитель : потомок уничтожен \n");

printf("Родитель : уничтожение семафора \n");

semctl( semid, 0, IPC_RMID);

printf("Родитель : освобождение общей памяти \n");

shmctl( mid, IPC_RMID, NULL);

return 0;

}

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

andrey@Andrey4623:~/laba4_1$ ./iEdit

Родитель : создание семафора

Родитель : инициализация общей памяти

Родитель : инициализация успешно завершена

Родитель : ожидание открытия семафора...

Потомок : процесс-поток создан

Потомок : открытие семафора...

Потомок : инициализация общей памяти

Потомок : запись в общую память

Потомок : записано число 400

Потомок : ожидание ответа от родителя

Родитель : считывание с общей памяти

Родитель : число равно 400

Родитель : начато открытие дочернего потока

Родитель : дочерний процесс разблокирован

Родитель : ожидание завершения потомка

Потомок : получен ответ от родителя ОК

Потомок : я уничтожен

Родитель : потомок уничтожен

Родитель : уничтожение семафора

Родитель : освобождение общей памяти



2. Программа-клиент записывает в файлы слова, которые посылает программа-сервер. По слову exit обе программы прекращают работать. Программа основана на очереди сообщений FIFO.

Сервер

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using namespace std;
#define MAXLINE 128

#define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)

#define FIFO1 "fifo.1"

#define FIFO2 "fifo.2"
int main( int argc, char **argv)

{

int readfd =-1, writefd = -1;

size_t n = 0;

char str[MAXLINE];

char str2[MAXLINE];

cout<<"Сервер запущен"<
unlink(FIFO1);

unlink(FIFO2);
if (mkfifo(FIFO1, FILE_MODE) == EEXIST)cout<<"\n Pipes is exist"<
if (mkfifo(FIFO2, FILE_MODE) == EEXIST)cout<<"\n Pipes is exist"<
cout<<"Набирайте слова"<
writefd = open(FIFO2, O_WRONLY);

if ((writefd!=-1)){

while (1){

cin>>str;

write(writefd, str, strlen(str));

readfd = open(FIFO1, O_RDONLY);

while ((n = read(readfd, str2, MAXLINE))>0) {

str2[n] =0;

cout<
break;

}

if (strcmp(str, "exit")==0) break;

}

close(readfd);

close(writefd);

unlink(FIFO1);

unlink(FIFO2);

cout<<"Сервер завершен"<}else cout<<"Невозможно открыть поток"<
return 0; }
Клиент

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using namespace std;

#define MAXLINE 128

#define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)

#define FIFO1 "fifo.1"

#define FIFO2 "fifo.2"
int main( int argc, char **argv)

{

int readfd =-1, writefd = -1;

size_t n = 0;

char str[MAXLINE];

char str2[MAXLINE];

ofstream cout("log.txt");

cout<<"Клиент запущен"<
while (1)

{

readfd = open(FIFO2, O_RDONLY, 0);

if (readfd!=-1)

{

while ((n=read(readfd, str, MAXLINE))>0)

{

str[n] = 0;

cout<
break;

}

strcpy(str2, "Подтверждение от клиента");

writefd = open(FIFO1, O_WRONLY,0);

write(writefd, str2, strlen(str2));

close(readfd);

close(writefd);

}

sleep(1);

if (strcmp(str, "exit") ==0) break;

}

cout<<"Клиент завершен";

cout.close();

return 0;

}

Результаты работы сервера:

andrey@Andrey4623:~/laba4_2$ ./server.exe

Сервер запущен

Набирайте слова

1

Подтверждение от клиента

2

Подтверждение от клиента

exit

Подтверждение от клиента

Сервер завершен



Результат работы клиента:

andrey@Andrey4623:~/laba4_2$ ./client.exe

Клиент запущен

1

2

exit

Клиент завершен



3. Программа-сервер записывает в очередь числа, программа-клиент считывает из очереди эти числа, считает их количество и сумму, удаляет очередь.

Сервер

#include

#include

#include

#include

#include

#include

#include

using namespace std;
#define MYKEY 4321L

#define FLAGS (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)

struct msg

{

long mtype;

int number;

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

{

printf("Сервер: очередь создана\n");

int msgid = msgget( ftok("maxim",0), FLAGS|IPC_CREAT);

cout<< msgid<
struct msg s_msg;

s_msg.mtype =1;

printf("Сервер: отправляем данные\n");

int k=0;

for (int i=1; i<100; i++)

{

s_msg.number = i;

msgsnd( msgid, &s;_msg, sizeof(s_msg), IPC_NOWAIT);

k+=i;

}

//printf("Сервер: количество чисел 99\n");

//printf("Cthdth : сумма %d\n", k);

printf("Сервер: завершаем работу");

return 0;
}

Клиент

#include

#include

#include

#include

#include

#include

#include

using namespace std;
#define MYKEY 4321L

#define FLAGS (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)

struct msg

{

long mtype;

int number;

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

{

printf("Клиент: очередь открыта\n");

int msgid = msgget(ftok("maxim", 0), FLAGS);

cout<
// if (msgid> 0)

{

struct msg c_msg;

c_msg.mtype =1;

printf("Клиент: чтение данных\n");
int count=0, sum =0;

while (msgrcv( msgid, &c;_msg,sizeof(c_msg), 0, IPC_NOWAIT)>0)

{

count++;

sum+=c_msg.number;

};

printf("Клиент : количество чисел %d\n", count);

printf("Клиент : сумма %d\n", sum);

printf("Клиент : очередь удалена \n");

msgctl( msgid, IPC_RMID, NULL);

}

printf("Клиент: завершаем работу");

return 0;
}
Результаты работы сервера:


andrey@Andrey4623:~/laba4_3$ ./server.exe

Сервер: очередь создана

0

Сервер: отправляем данные

Сервер: завершаем работу


Результат работы клиента:

andrey@Andrey4623:~/laba4_3$ ./client.exe

Клиент: очередь открыта

0

Клиент: чтение данных

Клиент : количество чисел 99

Клиент : сумма 198

Клиент : очередь удалена

Клиент: завершаем работу



Вывод: В ходе лабораторной работы мы познакомились с основными механизмами передачи данных и синхронизацией между процессами, такими как очереди сообщений, сегменты разделяемой памяти и синхронизация посредством семафоров. Изучили принципы работы потоков и команды bash по их управлению.


страница 1


скачать

Другие похожие работы: