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

Учащимся

Учителям



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



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

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

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

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





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

Кафедра ВТ

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

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

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

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


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

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

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

  2. Программа-клиент создаёт случайную последовательность случайной длины, программа-сервер должна определить количество чисел и их сумму (чисел не больше 100, все положительные и не превышают 100).

Листинг программы с общей памятью (синхронизация семафорами)

#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
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("Parent : Creating semaphore... \n");

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

arg.val = 2;

semctl( semid, 0, SETVAL, arg);

printf("Parent : initialization public memory \n");

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

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

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

printf("Parent : initialization OK \n");

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

{

printf(" Child : Child process was created...\n");

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

printf(" Child : opening semaphore... \n");

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

printf(" Child : initalization public memory\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(" Child : printing in memory\n");

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

int count= 1+ rand()%90;

int i;

int sum = 0;

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

for ( i=0; i
{

ch_ptr[i] =1+rand()%100;

sum += ch_ptr[i];

}

printf(" Child : the sum is %d \n", sum);

sleep(3);

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

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

printf(" Child : wait answer from Parent\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(" Child : reseved answer from Parent ");

if ( *ch_ptr == count) printf("OK"); else printf("Failure");

printf("\n Child : i'm die \n");

exit(0); }

printf("Parent : wait for unlock simaphore ..\n");

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

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

printf("Parent : unlocked by child,waiting for unlock child \n");

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

int j=0;

int psum =0;

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

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

printf("Parent : the sum is %d \n", psum);

sleep(2);

printf("Parent : start unlocking child\n");

pbuf.sem_num = pbuf.sem_flg = 0;

pbuf.sem_op = -1;

semop( semid, &pbuf, 1);

printf("Parent : unlock child\n");

printf("Parent : wait for chaild terminated\n");

waitpid( pid, NULL, 0);

printf("Parent : child, died \n");


printf("Parent : remove semaphor \n");

semctl( semid, 0, IPC_RMID);

printf("Parent : remove public memory \n");

shmctl( mid, IPC_RMID, NULL);

return 0;

}

Вывод программы:

Parent : Creating semaphore...

Parent : initialization public memory

Parent : initialization OK

Child : Child process was created...

Child : opening semaphore...

Child : initalization public memory

Child : printing in memory

Child : the sum is 212

Parent : wait for unlock simaphore ..

Child : wait answer from Parent

Parent : unlocked by child,waiting for unlock child

Parent : the sum is 212

Parent : start unlocking child

Child : reseved answer from Parent OK

Child : i'm die

Parent : unlock child

Parent : wait for chaild terminated

Parent : child, died

Parent : remove semaphor

Parent : remove public memory


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

Сервер

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include
#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<<"Server start..."<
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<<"You may type words..."<
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<<"Server is shut down"<
}else cout<<"can't open pipes.."<
return 0; }

Клиент

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include
#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<<"Client was running..."<
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, "ok from client");

writefd = open(FIFO1, O_WRONLY,0);

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

close(readfd);

close(writefd);

}

sleep(1);

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

}

cout<<"Client is shut down";

cout.close();

return 0;

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

Server start...

You may type words...

one

ok from client

two

ok from client

three

ok from client

exit

ok from client

Server is shut down
Результат работы клиента

Client was running..

one

two

three

exit

Client is shut down


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

Сервер

#include

#include

#include

#include

#include

#include
#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("Server :Make message queue\n");

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

cout<< msgid<
struct msg s_msg;

s_msg.mtype =1;

printf("Server :Sending messages\n");

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

{

s_msg.number = i;

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

}

printf("Server :Log out");

return 0;
}

Клиент

#include

#include

#include

#include

#include

#include
#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("Client :Open message queue\n");

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

cout<
// if (msgid> 0)

{

struct msg c_msg;

c_msg.mtype =1;

printf("Client :Receiving messages\n");
int count=0, sum =0;

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

{

count++;

sum+=c_msg.number;

};

printf("Client :The count is %d\n", count);

printf("Client :The sum is %d\n", sum);

printf("Client :Removing queue \n");

msgctl( msgid, IPC_RMID, NULL);

}

printf("Server :Log out");

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



страница 1


скачать

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