Отчет по лабораторной работе №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<<"Сервер завершен"<
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
скачать
Другие похожие работы: