Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
6262.pdf
Скачиваний:
34
Добавлен:
13.02.2021
Размер:
6.54 Mб
Скачать

 

164

sembuf [1].sem_num = no % qph;

// Правая

sembuf [1].sem_flg = 0;

// Операция с блокировкой

while (fo > 0) {

// Обед

// Философ говорит

printf ("lab10.3: Философ %d беседует\n", no); t = trnd; sleep (t); fo -= t;

//Пытается взять вилки sembuf [0].sem_op = -1; sembuf [1].sem_op = -1;

if (semop (semid, sembuf, 2) < 0) { perror ("lab10.3: SEMOP():"); return (1);

}

//Ест

printf ("Философ %d ест\n", no); t = ernd; sleep (t); fo -= t;

// Отдает вилки

sembuf [0].sem_op = 1; sembuf [1].sem_op = 1;

if (semop (semid, sembuf, 2) < 0) { perror ("lab10.3: semop():"); return (2);

}

}

printf ("lab10.3: Философ %d закончил обед\n", no); return 0;

}

Замечание

Откомпилированную программу-философ следует поместить, например, в директорию /home/upk/bin, тогда она может быть запущена без указания абсолютного пути ее расположения.

4.5.4 Программа-монитор

Для рассматриваемой задачи, учитывая, что количество обедающих философов задано некоторой константой QPH, алгоритм работы достаточно прост:

порождается набор семафоров QPH: по одному семафору на каждую вилку;

устанавливаются начальные значения семафоров: занятой вилке будет соответствовать значение 0, свободной — 1;

запускаются QPH процессов, каждый из которых представляет одного фило-

софа, передавая им в качестве аргументов: идентификатор набора семафоров, общее количество всех философов и место конкретного философа за столом: философы нумеруются от 1 до QPH;

ожидается, завершение работы всех процессов: когда все философы съедят свой обед;

удаляется весь набор семафоров.

Исходный текст такой программы-монитора демонстрируется на листинге 4.4.

165

Листинг 4.4 - Алгоритм программы-монитора, обеспечивающий работу процессов

#include <unistd.h> #include <stdio.h> #include <sys/sem.h> #include <sys/wait.h>

// Программа-монитор обеда философов

#define QPH 5

// Количество философов

#define ARG_SIZE 20

// Размер читаемых аргументов

int main (void) {

 

int key;

// Ключ набора семафоров

int semid;

// Идентификатор набора семафоров

int no;

// Номер философа и/или вилки

// Строки для аргументов дочерних процессов

char ssemid [ARG_SIZE], sno [ARG_SIZE], sqph [ARG_SIZE];

puts("Запущена программа: lab10.4");

// Создание и инициализация набора семафоров: по семафору на вилку key = ftok ("/home/upk/lab10", 2);

if ((semid = semget (key, QPH, 0600 | IPC_CREAT)) < 0) { perror ("SEMGET");

return (1);

}

for (no = 0; no < QPH; no++) {

// Значение семафора устанавливается в 1 if (semctl (semid, no, SETVAL, 1) < 0) {

perror ("SETVAL"); return (2);

}

}

//Подготовка аргументов

sprintf (ssemid,

"%d", semid);

sprintf (sqph,

"%d", QPH);

// Все - к столу

*/

for (no = 1; no <= QPH; no++) { switch (fork ()) {

case -1:

perror ("FORK"); return (3);

case 0:

sprintf (sno, "%d", no); //Подготовка аргументов

execlp ("lab10.3", "lab10.3", ssemid, sqph, sno, (char *) 0); perror ("EXEC");

return (4);

}

}

//Ожидание завершения обеда всех философов while (wait (NULL) > 0) ;

//Удаление набора семафоров

if (semctl (semid, 0, IPC_RMID) < 0) { perror ("SEMCTL");

return (5);

}

puts("lab10.4 - завершила работу..."); return 0;

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]