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

Учащимся

Учителям



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


ФЕДЕРАЛЬНОЕ АГЕНТСТВО ПО ОБРАЗОВАНИЮ
Государственное образовательное учреждение высшего профессионального образования
«ТОМСКИЙ ПОЛИТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ»
Факультет автоматики и вычислительной техники
Кафедра ВТ



Отчет по лабораторной работе №4

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

Выполнил:

студент гр. 8В53

Сидоров А. О.
Проверил:

доцент каф. ВТ

Шерстнев В.С.


Томск 2008

Цель работы


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

Ход работы

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

  2. Изучил работу команд для работы с процессами:

1. ps (process status) отображает статусы процессов, запущенных в системе.

2. jobs отображает список активных заданий

3. fg (foreground) служит для возобновления выполнения задания на переднем плане

4. bg (background) служит для запуска в фоновом режиме приостановленного процесса

5. kill позволяет уничтожить процесс

6. killall завершает процессы по имени



  1. Создал 3 приложения «клиент-сервер»

    1. Создал приложение «клиент-сервер», в котором родительский процесс (сервер) порождает дочерний процесс (клиент). Родительский поток размещает данные (символы) в разделяемой памяти, а дочерний считывает ее и анализирует (определяет, какие буквы хранятся в разделяемой памяти). При этом синхронизация потоков обеспечивается при помощи семафоров.

Исходный код:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

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

#define SKEY 1234L
union semun

{

int val;

struct semid_ds *buf;

ushort *array;

};
int main()

{

time_t seconds;

time(&seconds;);

srand((unsigned)seconds);
int asciiStart = 65;

int asciiFinish = 90;

int asciiShift = asciiFinish - asciiStart + 1;

//Semaphore initialization

int flag = SVSEM_MODE | IPC_CREAT;

int semid = semget(SKEY, 1, flag);

union semun arg;

struct semid_ds seminfo;

arg.buf = &seminfo;

arg.val = 1;

semctl(semid, 0, SETVAL, arg);

//!

//SharedMemory initialization

int length = 20;

int sharedMemoryId = shmget(ftok("sharedMemory", 0), length, flag);

char *sharedMemoryPointer;

struct shmid_ds sharedMemoryBuf;

//!

//Semaphore locking

struct sembuf sembuf;

sembuf.sem_num = 0;

sembuf.sem_flg = 0;

sembuf.sem_op = -1;

semop(semid, &sembuf;, 1);

//!

pid_t pid;

if ((pid = fork()) == 0)

{

//Semaphore locking

int childFlag = SVSEM_MODE | IPC_EXCL;

int childSemid = semget(SKEY, 1, childFlag);

struct sembuf childSembuf;

childSembuf.sem_num = 0;

childSembuf.sem_flg = 0;

childSembuf.sem_op = -1;

semop(semid, &childSembuf;, 1);

//!

sharedMemoryPointer = (char*)shmat(sharedMemoryId, NULL, 0);

shmctl(sharedMemoryId, IPC_STAT, &sharedMemoryBuf;);

char letters[asciiShift];

for (int i = 0; i < asciiShift; i++)

letters[i] = 0;

for (int i = 0; i < length; i++)

((int)letters[(int)*sharedMemoryPointer++ - asciiStart])++;

printf("Child: Shared memory contents:\n");

int k = 0;

for (int i = 0; i < asciiShift; i++)

{

if (((int)letters[i]) != 0)

{

printf("%c - %i\t", (char)(i + asciiStart), (int)letters[i]);

k++;

}

if (k == 5)

{

printf("\n");

k = 0;

}

}

if (k != 0)

printf("\n");

//Semaphore unlocking

childSembuf.sem_num = childSembuf.sem_flg = 0;

childSembuf.sem_op = 1;

semop(childSemid, &childSembuf;, 1);

//!

printf("Child: Exit\n\n");

exit(0);

}

printf("Parent: Start filling shared memory\n");

printf("Parent: Shared memory contents following characters: \n");

sharedMemoryPointer = (char*)shmat(sharedMemoryId, NULL, 0);

shmctl(sharedMemoryId, IPC_STAT, &sharedMemoryBuf;);

for (int i = 0; i < sharedMemoryBuf.shm_segsz; i++)

{

int number = rand() % asciiShift + asciiStart;

*sharedMemoryPointer++ = (char)number;

printf("%c ", (char)number);

}

printf("\n");

printf("Parent: Finish filling shared memory\n\n");

//Semaphore unlocking

sembuf.sem_num = sembuf.sem_flg = 0;

sembuf.sem_op = 1;

semop(semid, &sembuf;, 1);

//!

waitpid(pid, NULL, 0);

semctl(semid, 0, IPC_RMID);

shmctl(sharedMemoryId, IPC_RMID, NULL);

printf("Parent: Exit");

exit(0);

}

Скомплировал и запустил программу:



Скриншот демонстрирует алгоритм работы программы:

  1. Процесс1 блокирует семафор

  2. Процесс1 заполняет общую память

  3. Процесс1 разблокирует семафор и ждет завершения процесса2

  4. Процесс2 считывает данные из общей памяти и затем анализирует их

  5. Процесс2 завершает работу

  6. Процесс1 завершает работу

    1. Создал 2 приложения, взаимодействующих посредством именованных каналов. Приложение1 запрашивает отсутствующий у него функционал (метод Multiplicate) у приложения2.

Исходный код:

ira21.cpp:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include
#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH

#define FIFO1 "fifo1"

#define FIFO2 "fifo2"

#define MAXLINE 10
int main()

{

time_t seconds;

time(&seconds;);

srand((unsigned)seconds);
int readFd = -1, writeFd = -1;

unlink(FIFO1);

unlink(FIFO2);

mkfifo(FIFO1, FILE_MODE);

mkfifo(FIFO2, FILE_MODE);

writeFd = open(FIFO2, O_WRONLY);

if (writeFd == -1)

return 1;

readFd = open(FIFO1, O_RDONLY);

if (readFd == -1)

return 1;

char input1[MAXLINE];

int inp1 = rand() % 10 + 1;

sprintf(input1, "%i", inp1);

char input2[MAXLINE];

int inp2 = rand() % 10 + 1;

sprintf(input2, "%i", inp2);

write(writeFd, input1, MAXLINE);

write(writeFd, input2, MAXLINE);

char resultString[MAXLINE];

ssize_t n;

while ((n = read(readFd, resultString, MAXLINE)) > 0)

{

resultString[n] = 0;

break;

}
printf("Process1: Thank you, Process2! The result is ");

printf(resultString);

close(readFd);

close(writeFd);

unlink(FIFO1);

unlink(FIFO2);

exit(0);

}

ira22.cpp:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include
#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH

#define FIFO1 "fifo1"

#define FIFO2 "fifo2"

#define MAXLINE 10
int Multiplicate(int x, int y);
int main()

{

int readFd = -1, writeFd = -1;

readFd = open(FIFO2, O_RDONLY, 0);

if (readFd == -1)

return 1;

writeFd = open(FIFO1, O_WRONLY, 0);

if (writeFd == -1)

return 1;
char input1[MAXLINE];

char input2[MAXLINE];

ssize_t n;

while ((n = read(readFd, input1, MAXLINE)) > 0)

{

input1[n] = 0;

break;

}

int inp1 = atoi(input1);

printf("Process2: Received inp1 = %i\n", inp1);

while ((n = read(readFd, input2, MAXLINE)) > 0)

{

input2[n] = 0;

break;

}

int inp2 = atoi(input2);

printf("Process2: Received inp2 = %i\n", inp2);

printf("Process2: Starting calculations\n");

int result = Multiplicate(inp1, inp2);

char resultString[MAXLINE];

sprintf(resultString, "%i", result);

printf("Process2: Finished calculations\n");

printf("Process2: Sending the result...\n");

write(writeFd, resultString, MAXLINE);

close(readFd);

close(writeFd);

}
int Multiplicate(int x, int y)

{

return x * y;

}

Скомпилировал и запустил созданные приложения:

Процесс ira21.exe запускается в фоновом режиме. После запуска ira22.exe получает два исходящих параметра от процесса ira21.exe. Совершив необходимые вычисления, процесс ira22.exe отправляет ответ ira21.exe, за что тот его весьма вежливо благодарит.

    1. Создал 3 приложения, взаимодействующих при помощи очередей сообщений. Приложение1 реагирует текст, вводимый в консоль, и вызывает сообщения, которые обрабатываются приложением2 и приложением3.

Исходный код:

ira41.cpp:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include
struct

{

long mtype; /* тип сообщения */

char Data[256]; /* сообщение */

} Message;
int main()

{

key_t key;

int msgid;

char str[256];

key=ftok("message",0);

msgid=msgget(key, 0666 | IPC_CREAT);

while (true)

{

gets(str);

strcpy(Message.Data, str);

switch(str[0])

{

case '2': Message.mtype=1;

msgsnd(msgid, (struct msgbuf*) (&Message;), strlen(str)+1, 0);

break;

case '3': Message.mtype=2;

msgsnd(msgid, (struct msgbuf*) (&Message;), strlen(str)+1, 0);

break;

case 'q': Message.mtype=1;

msgsnd(msgid, (struct msgbuf*) (&Message;), strlen(str)+1, 0);

Message.mtype=2;

msgsnd(msgid, (struct msgbuf*) (&Message;), strlen(str)+1, 0);

sleep(10);

msgctl(msgid, IPC_RMID, NULL);

exit(0);

default: break;

}

}

}

ira42.cpp:

#include

#include

#include

#include

#include

#include

#include

#include

#include
struct

{

long mtype;

char Data[256];

} Message;
int main()

{

key_t key;

int msgid;

key=ftok("message",0);

msgid=msgget(key, 0666 | IPC_CREAT);

while (true)

{

msgrcv(msgid, (struct msgbuf*)(&Message;), 256, 1, 0);

if (Message.Data[0]=='q')

break;

printf("Process2: %s \n", Message.Data);

}

//exit(0);

}

ira43.cpp:

#include

#include

#include

#include

#include

#include

#include

#include

#include
struct

{

long mtype;

char Data[256];

} Message;
int main()

{

key_t key;

int msgid;

key=ftok("message", 0);

msgid=msgget(key, 0666 | IPC_CREAT);

while (true)

{

msgrcv(msgid, (struct msgbuf*)(&Message;), 256, 2, 0);

if (Message.Data[0]=='q')

break;

printf("Process3: %s \n", Message.Data);

}

//exit(0);

}

Скомпилировал и запустил приложения:



Скриншот демонстрирует, что при нажатии «2» событие перехватывает приложение2, при нажатии «3» - приложение3, а нажатие q завершает работу приложений.

Выводы

В ходе выполнения лабораторной работы был изучен объект процесс, основные механизмы передачи данных между процессами (очереди сообщений, сегменты разделяемой памяти и каналы), а также синхронизация взаимодействующих процессов в ОС Unix.посредством семафоров.

страница 1


скачать

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