Министерство Образования Российской Федерации
Хабаровский Государственный Технический Университет
Лабораторная работа №7
По дисциплине «Операционные системы»
Тема: «Межпроцессные коммуникации – использование общей памяти»Цель работы: Изучение механизма межпроцессных коммуникаций в ОС Linux, использующего общую память. Знакомство с функциями IPC для создания и управления сегментами общей памяти.
Задание:
Описание функционирования программы:
После запуска программы с параметром (число дочерних процессов, запускаемых главным процессом) главный (родительский) процесс создаёт дочерние процессы (описание далее), потоки (описание далее) и общую область памяти с ключом 32547, которую присоединяет к себе, после чего заполняет эту область случайными числами, которые в дальнейшем будут обработаны дочерними процессами. Активизирует созданные потоки, захватывает мьютекс и попадает в цикл, который оканчивается после завершения всех дочерних процессов (пока число живых дочерних процессов не станет равно нулю). В этом цикле главный процесс ожидает сигнала от другого потока, после получения которого сообщает о наличии в общей области памяти запроса “m” (more) на выдачу числа, генерирует это число и выставляет в общей памяти. Повторяет цикл. После завершения цикла освобождает мьютекс, удаляет область общей памяти и программа корректно завершается.
Поток работает следующим образом: ждёт, пока родительский процесс активизирует его, начинает выполнять цикл, в котором читает область общей памяти. Когда приходит символ “m”, захватывает мьютекс, передаёт свой номер родительскому процессу через глобальную переменную и посылает ему сигнал “пробуждения”, после чего освобождает мьютекс.
Функционирование дочернего процесса: присоединяет к себе общую область памяти, созданную родительским процессом, прибавляет к сумме число, записанное в этой области, и начинает выполнять цикл, в котором выдаёт запрос “m” на выдачу нового числа и ждёт появления этого числа. После получения, прибавляет его к сумме и повторяет цикл до тех пор, пока сумма не превысит заданное. После выполнения цикла дочерний процесс записывает в общую область памяти букву “e” (end – готовность к убийству), оповещает родительский процесс сигналом и ждёт своей участи. Родительский процесс обрабатывает этот сигнал следующим образом: сканирует область общей памяти на наличие буквы “e”, найдя эту букву, киляет тот процесс, который её туда поместил, помечает память буквой “k” (killed - означает, что процесс убит) и уменьшает счётчик живых дочерних процессов. Если число живых процессов равно нулю, то посылает сигнал родительскому процессу.
Текст и результат работы программы:
Листингпрограммы:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
#define SUM 10
int cond_sig=0;
int PIDs[100];
int cnt_alive_chd, start_thrds, gl_n, shmid, k;
pthread_mutex_t my_mux, end_mux;
pthread_cond_t gl_cond;
time_t curtime;
char *shm;
/*begin of SigHndlr*/
void SigHndlr()
{
pthread_mutex_lock(&end_mux);
int i;
for(i=0;i<k;i++)
if(shm[i]=='e')
{
shm[i]='k';
kill(PIDs[i],SIGKILL);
time(&curtime);
printf("!!!KILLED!!! child #%d (PID=%d). Current time: %s",i,PIDs[i],ctime(&curtime));
cnt_alive_chd--;
}
if(cnt_alive_chd==0)
{
cond_sig=1;
pthread_cond_signal(&gl_cond);
}
pthread_mutex_unlock(&end_mux);
}
/*end of SigNndlr*/
/*begin of read_thread*/
void *read_thrd(void *p)
{
int num_of_chl;
num_of_chl=(int)p;
while(start_thrds!=1){};
while(1)
{
while(shm[num_of_chl]!='m')usleep(100000);
pthread_mutex_lock(&my_mux);
gl_n=num_of_chl;
cond_sig=1;
pthread_cond_signal(&gl_cond);
pthread_mutex_unlock(&my_mux);
}
}
/*end of read_thread*/
/*begin of parent*/
void parent_prc()
{
start_thrds=1;
pthread_mutex_lock(&my_mux);
while(cnt_alive_chd!=0)
{
while(cond_sig!=1){pthread_cond_wait(&gl_cond,&my_mux);}
if(cnt_alive_chd!=0)
{
cond_sig=0;
time(&curtime);
printf("Parent (PID=%d) RECV \"m\" from child #%d. Current time: %s",getpid(),gl_n,ctime(&curtime));
shm[gl_n]=rand()%5;
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.