Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
0 / 0 / 0
Регистрация: 05.03.2014
Сообщений: 9

Обедающие философы

28.09.2015, 18:40. Показов 3299. Ответов 0
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Задача звучит так:
В пансионе отдыхают и предаются размышлениям N философов, пронумерованные от 1 до N.
В столовой расположен круглый стол, вокруг которого расставлены N стульев, также
пронумерованные от 1 до N. На столе находится одна большая тарелка с едой, которая пополняется
бесконечно. Там же расставлены N тарелок, в которые накладывается еда, и N вилок, назначение
которых очевидно. При этом M стульев предназначены для конкретных M философов (причем, 0 <=
M < N) с заданными пользователем номерами.
Для того чтобы пообедать, философ входит в столовую и может сесть на любой стул, при условии,
что он не предназначен для другого определенного философа. Этот последний может обедать только
на стуле со своим номером. При этом принимать пищу любой философ сможет только в том случае,
если свободны две вилки – справа и слева от тарелки. При выполнении данного условия философ
поднимает одновременно обе вилки и может поглощать пищу в течение какого-то заданного времени.
В противном случае, философу приходится ждать освобождения обеих вилок. Пообедав, философ
кладет обе вилки на стол одновременно и уходит предаваться размышлениям.
Описанный процесс происходит до явной команды пользователя на завершение работы. Ввод
значений N и M и бронирование стульев за конкретным философом осуществляется пользователем.

Не знаю, как добавить стулья. Т.е. чтобы философы с зарезервированными стульями садились на свои стулья, а остальные философы на оставшиеся свободные.

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <assert.h>
#include <time.h>
#include <stdlib.h>
#include <semaphore.h>
#include <string.h>
#define LEFT (i + N - 1) % N //макрос, определяющий номер левого философа
#define RIGHT (i + 1) % N //макрос, определяющий номер правого философа
#define THINKING 0 //код состояния, когда философ размышляет
#define HUNGRY 1 //код состояния, когда философ хочет поесть (ожидает вилки)
#define EATING 2 //код состояния, когда философ ест
#define MAX_TIME 5 //максимальное время, которое может быть потрачено на еду и/или на размышления
 
int N; //количество философов
int M; //количество занятых стульев
sem_t *mutex = NULL; //взаимное исключение входа в критическую область (взять - положить вилки)
sem_t *eaters = NULL; //указатель на sem_t, которые впоследствии станет указателем на массив из N семафоров
int* state = NULL; //указатель на массив int'ов, характеризующий состояния философов
int* chairs = NULL;
 
//процесс поедания
void eat(int i) {
        int time = rand() % MAX_TIME;
        printf("Философ #%d ест...\n", i + 1);
        sleep(time);
        printf("Философ #%d прекратил есть и пошел предаваться размышлениям...\n", i + 1);
}
 
void sitdown(int i) {
        int time = rand() % MAX_TIME;
        printf("Философ #%d сел\n", i + 1);
        sleep(time);
}
 
//проверка, сможет ли приступить к еде голодный i-й философ...
void test(int i) {
        //если сам философ голоден, а его соседи не едят (то есть вилки свободны)
        if (state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT] != EATING) {
                state[i] = EATING; //меняем статус, что наш i-й философ поел
                sem_post(&eaters[i]); //философ начал есть, поэтому инкрементируем семафор, чтобы философа не заблокировали соседи
        }
}
 
//i-й философ пытается взять вилку...
void take_sticks(int i) {
        sem_wait(mutex); //входим в критическую область, чтобы с вилками на данный момент работал только один философ
        state[i] = HUNGRY; //i-й философ теперь хочет есть (а он либо поест, либо не поест сразу, всё зависит от того, не едят ли его соседи...)
        test(i); //попытка взять две вилки...
        sem_post(mutex); //выходим из критической области
        sem_wait(&eaters[i]); //если не удалось начать есть (то есть sem_post не выполнился, и семафор равен нулю), то он блокируется.
        //разблокировать его смогут соседи после приёма пищи
}
 
void put_sticks(int i) {
        sem_wait(mutex); //входим в критическую область, чтобы с вилками на данный момент работал только один философ
        state[i] = THINKING; //i-й философ наелся, теперь начал думать
        test(LEFT); //проверяем, если сосед слева голоден (то есть ожидают вилку), то даём ему сигнал, чтобы они начали есть 
//Я позволил себе убрать комментарий от test(RIGHT), очевидно поставленный для отладки.
        test(RIGHT); //аналогично с правым соседом... 
//
        sem_post(mutex);
}
 
 
//код, выполняющийся каждым потоком (характеризующий поведение философа)
void* philosopher(void* arg) {
        int i = *((int*)arg);
        while (1 == 1) { //бесконечный цикл
                sitdown(i);
                take_sticks(i); //затем берёт вилки (или, если быть точнее, пытается взять)
                eat(i); //ест
                put_sticks(i); //кладёт вилки обратно
        }
}
 
 
 
int main(int argc, char* argv[]) {
printf ("Введите количество философов: ");
        scanf ("%d", &N);
printf ("Введите число забронированных стульев: ");
scanf ("%d", &M);
int i;
        mutex = (sem_t*)malloc(sizeof(sem_t));
        if (sem_init(mutex, 0, 1) != 0) { //создаём мьютекс для разграничения доступа к критической области
                fprintf(stderr, "Ошибка при создании семафора...\n");
                return 3;
        }
 
        eaters = (sem_t*)calloc(N, sizeof(sem_t)); //выделяем память под N семафоров, характеризующих философов
        state = (int*)calloc(N, sizeof(int)); //выделяем память под N целочисленных аргументов, характеризующие состояния философов 
        
        memset(state, 0, N);
 
        srand(time(NULL));
        pthread_t *philosophers = (pthread_t*)malloc(N * sizeof(pthread_t)); //выделяем память под N потоков, символизирующие философов
 
        for (i = 0; i < N; i++) {
                if (sem_init(&eaters[i], 0, 0) != 0) { //создаём N семафоров
                        fprintf(stderr, "Ошибка при создании семафора...\n");
                        return 3;
                }
        }
        
        int *t = (int *)malloc(sizeof(int));
        for (i = 0; i < N; i++) {
                *t = i;
                if (pthread_create(&philosophers[i], NULL, philosopher, t) != 0) { //создаём потоки
                        fprintf(stderr, "Ошибка при создании потока\n");
                        return 2;
                }
        usleep(10000);
    }
        
        void* result;
        for (i = 0; i < N; i++) {
                if (philosophers[i] != -1) {
                        if (pthread_join(philosophers[i], &result) != 0) {
                                fprintf(stderr, "Ошибка\n");
                                return 3;
                        }
                }
        }
        return 0;
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
28.09.2015, 18:40
Ответы с готовыми решениями:

Обедающие философы
Всем привет. Нужна помощь в решении задач об обедающих философах с помощью семафоров, мониторов и блокировки. Также нужно добавить главный...

Обедающие философы
Здравствуйте участники форума я на форуме нашел программу про обедающих философов вот её исходники using System; using...

Обедающие философы
Добрый вечер! Возник такой вот вопрос: Есть стандартная задача с обедающими философами, описанная в книге Таненбаума. Но...

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
28.09.2015, 18:40
Помогаю со студенческими работами здесь

Процессы, Обедающие философы
Здравствуйте! Нужна помощь с задачей о обедающих философах сделанная не на потоках как здесь...

Обедающие философы, Critical Section
Задача: Есть 5 философов. В столовой расположен круглый стол, вокруг которого расставлены 5 стульев. На столе находится одна большая...

Обедающие философы, перевод с Delphi
«Проблема обедающих философов» Программная реализация задачи на языке Delphi, нужно перевести в с# windows forms main.pas unit...

Обедающие философы. Решение методом монитора
Здравствуйте. Ищу решения проблемы обедающих философов методом монитора( он же официант, арбитр и т.д.) Есть у кого готовый код?

Обедающие философы, уменьшить возможность возникновения deadlock-а
Есть программа, которая решает задачу обедающих философов.public class Phil { int pos; Fork left; Fork right; int...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Новые блоги и статьи
1С: Программный отбор элементов справочника Номенклатура по группе
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор по наименованию группы. . .
Как я обхитрил таблицу Word
Alexander-7 21.03.2026
Когда мигает курсор у внешнего края таблицы, и нам надо перейти на новую строку, а при нажатии Enter создается новый ряд таблицы с ячейками, то мы вместо нервных нажатий Энтеров мы пишем любые буквы. . .
Krabik - рыболовный бот для WoW 3.3.5a
AmbA 21.03.2026
без регистрации и смс. Это не торговля, приложение не содержит рекламы. Выполняет свою непосредственную задачу - автоматизацию рыбалки в WoW - и ничего более. Однако если админы будут против -. . .
1С: Программный отбор элементов справочника Сотрудники по значению перечисления
Maks 21.03.2026
Установка программного отбора элементов справочника "Сотрудники" из модуля формы документа. В качестве фильтра для отбора служит предопределенное значение перечислений. Процедура. . .
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru