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

Учащимся

Учителям



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



Федеральное агентство по образованию

Государственное образовательное

учреждение высшего профессионального образования

«ТОМСКИЙ ПОЛИТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ»





Факультет автоматики и вычислительной техники

Кафедра ВТ

ЛАБОРАТОРНАЯ РАБОТА №4
по дисциплине

«Операционные системы»
Выполнил:

Студент группы 8В51 _________ М. С. Гриценко
Руководитель:

_________ А. В. Замятин


Томск – 2008
Цель: практическое знакомство с объектом процесс, основными механизмами передачи данных между процессами, а также синхронизацией взаимодействующих процессов в ОС Unix.

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

  1. Ознакомились с теоретическим материалом

  2. Программа-клиент создаёт случайную последовательность случайной длины, программа-сервер должна определить количество чисел и их сумму (чисел не больше 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 semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
};


int main( int argc, char *argv[])
{
pid_t pid; // идентификатор дочернего процесса
union semun arg;
struct sembuf pbuf;

//srand((unsigned)time(NULL));
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 semun 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
Родитель : начато открытие дочернего потока
Родитель : дочерний процесс разблокирован
Родитель : ожидание завершения потомка
Потомок : получен ответ от родителя ОК
Потомок : я уничтожен
Родитель : потомок уничтожен
Родитель : уничтожение семафора
Родитель : освобождение общей памяти


  1. Программа-клиент записывает в файлы слова, которые посылает программа-сервер. По слову 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$

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

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

1

2

exit

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


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

Сервер

#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$
andrey@Andrey4623:~/laba4_3$ ./client.exe
Клиент: очередь открыта
0
Клиент: чтение данных
Клиент : количество чисел 99
Клиент : сумма 198
Клиент : очередь удалена
Клиент: завершаем работуandrey@Andrey4623:~/laba4_3$

Выводы:В ходе проделанной лабораторной работы мы познакомились с основными механизмами передачи данных между процессами, а также их синхронизацией. Синхронизация процессов мало отличается от синхронизации потоков, поэтому это очень важное и кропотливое дело.



страница 1


скачать

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