0 / 0 / 0
Регистрация: 05.03.2014
Сообщений: 9

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

28.09.2015, 18:40. Показов 3301. Ответов 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
Ответ Создать тему
Опции темы

Новые блоги и статьи
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной записи. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
Контроль уникальности заводского номера - вариант №2
Maks 24.03.2026
В отличие от предыдущего варианта добавлено прерывание циклов, также добавлены новые переменные для сохранения контекста ошибки перед прерыванием цикла: Процедура ПередЗаписью(Отказ, РежимЗаписи,. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
Контроль уникальности заводского номера - вариант №1
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере документа выдачи шин для спецтехники с табличной частью в конфигурации КА2. Данные берутся из регистра сведений, по. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru