Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 52, средняя оценка - 4.62
programmerC++
3 / 3 / 1
Регистрация: 04.11.2010
Сообщений: 38
#1

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

05.11.2010, 17:52. Просмотров 7022. Ответов 17
Метки нет (Все метки)

Здравствуйте участники форума я на форуме нашел программу про обедающих философов вот её исходники
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
 
namespace Philosopher
{
    public class Philosopher_1
    {
        public static void Phil_1_eat()
        {
            while (true)
            {
                Global.Think.WaitOne();
                Console.WriteLine("Философ 1 размышляет");
                Thread.Sleep(1000);
                Global.Think.Release();
 
                Global.ToHungry.WaitOne();
                Console.WriteLine("Философ 1 голоден");
                Thread.Sleep(1000);
                Global.FromHungry.Release();
 
            check_1:
                {
                    if (Global.vhod_control == 2)
                    {
                        Global.ToHungry.WaitOne();
                        Console.WriteLine("Философ 1 голоден");
                        Thread.Sleep(1000);
                        Global.FromHungry.Release();
                    }
                    else
                        goto check_1_1;
                }
                goto check_1;
            check_1_1:
 
                Global.Eat.WaitOne();
                Global.vhod_control = Global.vhod_control + 1;
                Console.WriteLine("Философ 1 ест");
                Thread.Sleep(1000);
                Global.vhod_control = Global.vhod_control - 1;
                Global.Eat.Release();
            }
        }
    }
 
    public class Philosopher_2
    {
        public static void Phil_2_eat()
        {
            while (true)
            {
                Global.Think.WaitOne();
                Console.WriteLine("Философ 2 размышляет");
                Thread.Sleep(1000);
                Global.Think.Release();
 
                Global.ToHungry.WaitOne();
                Console.WriteLine("Философ 2 голоден");
                Thread.Sleep(1000);
                Global.FromHungry.Release();
 
            check_2:
                {
                    if (Global.vhod_control == 2)
                    {
                        Global.ToHungry.WaitOne();
                        Console.WriteLine("Философ 2 голоден");
                        Thread.Sleep(1000);
                        Global.FromHungry.Release();
                    }
                    else
                        goto check_2_1;
                }
                goto check_2;
            check_2_1:
 
                Global.Eat.WaitOne();
                Global.vhod_control = Global.vhod_control + 1;
                Console.WriteLine("Философ 2 ест");
                Thread.Sleep(1000);
                Global.vhod_control = Global.vhod_control - 1;
                Global.Eat.Release();
            }
        }
    }
 
    public class Philosopher_3
    {
        public static void Phil_3_eat()
        {
            while (true)
            {
                Global.Think.WaitOne();
                Console.WriteLine("Философ 3 размышляет");
                Thread.Sleep(1000);
                Global.Think.Release();
 
                Global.ToHungry.WaitOne();
                Console.WriteLine("Философ 3 голоден");
                Thread.Sleep(1000);
                Global.FromHungry.Release();
 
            check_3:
                {
                    if (Global.vhod_control == 2)
                    {
                        Global.ToHungry.WaitOne();
                        Console.WriteLine("Философ 3 голоден");
                        Thread.Sleep(1000);
                        Global.FromHungry.Release();
                    }
                    else
                        goto check_3_1;
                }
                goto check_3;
            check_3_1:
 
                Global.Eat.WaitOne();
                Global.vhod_control = Global.vhod_control + 1;
                Console.WriteLine("Философ 3 ест");
                Thread.Sleep(1000);
                Global.vhod_control = Global.vhod_control - 1;
                Global.Eat.Release();
            }
        }
    }
 
    public class Philosopher_4
    {
        public static void Phil_4_eat()
        {
            while (true)
            {
                Global.Think.WaitOne();
                Console.WriteLine("Философ 4 размышляет");
                Thread.Sleep(1000);
                Global.Think.Release();
 
                Global.ToHungry.WaitOne();
                Console.WriteLine("Философ 4 голоден");
                Thread.Sleep(1000);
                Global.FromHungry.Release();
 
            check_4:
                {
                    if (Global.vhod_control == 2)
                    {
                        Global.ToHungry.WaitOne();
                        Console.WriteLine("Философ 4 голоден");
                        Thread.Sleep(1000);
                        Global.FromHungry.Release();
                    }
                    else
                        goto check_4_1;
                }
                goto check_4;
            check_4_1:
 
                Global.Eat.WaitOne();
                Global.vhod_control = Global.vhod_control + 1;
                Console.WriteLine("Философ 4 ест");
                Thread.Sleep(1000);
                Global.vhod_control = Global.vhod_control - 1;
                Global.Eat.Release();
            }
        }
    }
 
    public class Philosopher_5
    {
        public static void Phil_5_eat()
        {
            while (true)
            {
                Global.Think.WaitOne();
                Console.WriteLine("Философ 5 размышляет");
                Thread.Sleep(1000);
                Global.Think.Release();
 
                Global.ToHungry.WaitOne();
                Console.WriteLine("Философ 5 голоден");
                Thread.Sleep(1000);
                Global.FromHungry.Release();
 
            check_5:
                {
                    if (Global.vhod_control == 2)
                    {
                        Global.ToHungry.WaitOne();
                        Console.WriteLine("Философ 5 голоден");
                        Thread.Sleep(1000);
                        Global.FromHungry.Release();
                    }
                    else
                        goto check_5_1;
                }
                goto check_5;
            check_5_1:
 
                Global.Eat.WaitOne();
                Global.vhod_control = Global.vhod_control + 1;
                Console.WriteLine("Философ 5 ест");
                Thread.Sleep(1000);
                Global.vhod_control = Global.vhod_control - 1;
                Global.Eat.Release();
            }
        }
    }
 
    class Global
    {
        public static int vhod_control = 0;
        public static int s = 100;
        public static int t = 100;
        public static int n = 2;
        public static Semaphore Eat = new Semaphore(n, n);
        public static Semaphore FromThink = new Semaphore(0, s);
        public static Semaphore Think = new Semaphore(s, s);
        public static Semaphore FromHungry = new Semaphore(0, t);
        public static Semaphore ToHungry = new Semaphore(t, t);
 
        static void Main(string[] args)
        {
            Thread Thread_1 = new Thread(new ThreadStart(Philosopher_1.Phil_1_eat));
            Thread_1.Start();
 
            Thread Thread_2 = new Thread(new ThreadStart(Philosopher_2.Phil_2_eat));
            Thread_2.Start();
 
            Thread Thread_3 = new Thread(new ThreadStart(Philosopher_3.Phil_3_eat));
            Thread_3.Start();
 
            Thread Thread_4 = new Thread(new ThreadStart(Philosopher_4.Phil_4_eat));
            Thread_4.Start();
 
            Thread Thread_5 = new Thread(new ThreadStart(Philosopher_5.Phil_5_eat));
            Thread_5.Start();
        }
    }
}
но в данном коде ошибка, когда ест философ:1, тогда философ:2 не может есть, а он ест. Как это исправить?
Должно быть так: только 2 философа могут есть и с расчетом через одного, так как им надо по 2 вилки, как они закончат приём пищи, могут начинать другие.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.11.2010, 17:52     Обедающие философы
Посмотрите здесь:

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

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Nick Alte
Эксперт С++
1608 / 1000 / 118
Регистрация: 27.09.2009
Сообщений: 1,927
Завершенные тесты: 1
05.11.2010, 17:57     Обедающие философы #2
Дааа... воистину китайское трудолюбие... Хорошо, что философов 5, а не 2048...
Saiberg
19 / 19 / 1
Регистрация: 23.09.2010
Сообщений: 193
05.11.2010, 18:00     Обедающие философы #3
а это случайно не шарп ?)

P.S. в этом разделе вроде плюсы
programmerC++
3 / 3 / 1
Регистрация: 04.11.2010
Сообщений: 38
05.11.2010, 18:04  [ТС]     Обедающие философы #4
Nick Alte, Saiberg, вы лучше скажите как исправить алгоритм=)
Nick Alte
Эксперт С++
1608 / 1000 / 118
Регистрация: 27.09.2009
Сообщений: 1,927
Завершенные тесты: 1
05.11.2010, 18:05     Обедающие философы #5
Почему бы для начала не сделать один-единственный класс на всех философов?
programmerC++
3 / 3 / 1
Регистрация: 04.11.2010
Сообщений: 38
05.11.2010, 18:15  [ТС]     Обедающие философы #6
Saiberg, да это шарп, промахнулся при выборке =)

Nick Alte, у вас есть идеи?
Nick Alte
Эксперт С++
1608 / 1000 / 118
Регистрация: 27.09.2009
Сообщений: 1,927
Завершенные тесты: 1
05.11.2010, 18:19     Обедающие философы #7
- Есть ли у вас план, мистер Фикс?
- Да! У меня есть план! У меня есть даже два плана!
Идея простая. Надо сделать единый класс вместо пяти, которые делают абсолютно одно и то же. Внести в них данные и объекты синхронизации, относящиеся непосредственно к объекту "философ". Переделать Main соответственно. И уж тогда и посмотреть, что получается. И если что-то не то, то почему оно так.
programmerC++
3 / 3 / 1
Регистрация: 04.11.2010
Сообщений: 38
05.11.2010, 18:26  [ТС]     Обедающие философы #8
Nick Alte, ну тогда чего медлить мистер Фикс!!! =)
KpeHDeJIb
56 / 56 / 3
Регистрация: 31.10.2010
Сообщений: 103
05.11.2010, 18:29     Обедающие философы #9
Весь смысл парадокса про обедающих философов в том, что может случиться deadlock, т.е.тупик, когда каждый философ возьмет по вилке то они будут бесконечно долго ждать вторую вилку. Так что поясните мне в чем смысл данной программы? )
programmerC++
3 / 3 / 1
Регистрация: 04.11.2010
Сообщений: 38
05.11.2010, 18:40  [ТС]     Обедающие философы #10
KpeHDeJIb, смотрите философы не могут есть вечно, кто то из них по ест и положит вилку следовательно другой начнет есть.

Добавлено через 9 минут
есть ещё такой вариант
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
#include <process.h>
#include <stdio.h>
#include<windows.h>
#include<iostream>
#include<time.h>
 
using namespace std;
 
#define N 5             //Число философов
#define LEFT (i-1)%N    //Левый сосед философа с номером i
#define RIGHT (i+1)%N   //Правый сосед философа сномером i
#define THINKING 0      //Философ размышляет
#define HUNGRY 1        //Философ получается получить вилки
#define EATING 2        //Философ ест
                        
int state[N];           //Состояния каждого философа
 
 
struct Philosopher      //Описание философа: номер, алгоритм
{
    int number;
    int algorithm;
};
 
struct Forks            //Описывает количество вилок у философа
{
    int left;           //0-нет вилки 
    int right;          //1-есть вилка
}forks[N];
 
 
CRITICAL_SECTION cs;        //Для критических секций: синхрон. процессов    
CRITICAL_SECTION cs_forks;  //и синхр. вилок
 
HANDLE philMutex[N];    //Каждому философу по мьютексу
HANDLE forkMutex[N];    //и каждой вилке
 
void think(int i)       //Моделирует размышления философа
{
    EnterCriticalSection( &cs );    //Вход в критическую секцию
    cout<<"Philosopher number "<<i<<" thinking"<<endl;
    LeaveCriticalSection( &cs );    //Выход из критической секции
}
 
void eat(int i)         //Моделирует обед философа
{
    EnterCriticalSection( &cs );    //Вход в критическую секцию
    cout<<"Philosopher number "<<i<<" eating"<<endl;
    LeaveCriticalSection( &cs );    //Выход из критической секции
}
 
void test(int i)    //Проверка возможности начать философом обед
{
    if(state[i]==HUNGRY&&state[LEFT]!=EATING&&state[RIGHT]!=EATING)
    {
        state[i]=EATING;
        ReleaseMutex( philMutex[i] );
 
    }
}
 
void take_forks(int i)  //Взятие вилок
{
    EnterCriticalSection( &cs_forks );              //Вход в критическую секцию
    state[i]=HUNGRY;                                //Фиксация наличия голодного философа
    test(i);                                        //Попытка получить две вилки
    LeaveCriticalSection( &cs_forks );              //Выход из критической секции
    WaitForSingleObject( philMutex[i], INFINITE );  //Блокировка если вилок не досталось
 
 
}
 
void put_forks(int i)   //Философ кладет вилки обратно
{
    EnterCriticalSection( &cs_forks );  //Вход в критическую секцию 
    state[i]=THINKING;                  //Философ перестал есть
    test(LEFT);                         //Проверить может ли есть сосед слева
    test(RIGHT);                        //Проверить может ли есть сосед справа
    LeaveCriticalSection( &cs_forks );  //Выход из критической секции
}
 
void take_left_fork(int i)  //Попытка взять левую вилку
{
    EnterCriticalSection( &cs );
    WaitForSingleObject( forkMutex[LEFT], INFINITE );   //Если вилка свободна   
    forks[i].left=1;                                    //Берем ее
    LeaveCriticalSection( &cs );
 
}
 
void put_left_fork(int i)   //Кладем левую вилку
{
    WaitForSingleObject( forkMutex[LEFT], INFINITE );   
    forks[i].left=0;            //Кладем вилку
    ReleaseMutex( forkMutex[LEFT] );
 
}
 
void take_right_fork(int i) //Попытка взять правую вилку
{
    EnterCriticalSection( &cs );
    WaitForSingleObject( forkMutex[RIGHT], INFINITE );  //Если вилка свободна   
    forks[i].right=1;                                   //Берем ее
    LeaveCriticalSection( &cs );
 
}
 
void put_right_fork(int i)  //Кладем правую вилку
{
    WaitForSingleObject( forkMutex[RIGHT], INFINITE );  
    forks[i].right=0;           //Кладем вилку
    ReleaseMutex( forkMutex[RIGHT] );
 
}
int test_fork(int i)    //Проверяем наличи у философа обеих вилок
{
    if(forks[i].left==1&&forks[i].right==1) //Если обе
    {
        ReleaseMutex( forkMutex[LEFT] );    //Разрешаем положить вилки
        ReleaseMutex( forkMutex[RIGHT] );   //
        return 1;                                   //Едим
    }
    else
        return 0;
}
 
DWORD WINAPI philosopher(void *lParam)  //Собственно модель философа
{   
    Philosopher phil=*((Philosopher *)lParam);  //Получаем модель философа
    
    while(1)    //Моделируем обед
    {   //Берем вилки
        if(phil.algorithm==0)   //Берем первой левую вилку
        {
            think(phil.number); //Думаем
            take_left_fork(phil.number);    //Берем левую
            take_right_fork(phil.number);   //и правую вилки
            if(test_fork(phil.number)==1)           //Если обе 
                eat(phil.number);                   //то едим
        }
        else
            if(phil.algorithm==1)   //Берем первую вилку случайно
            {
                int n=rand()%2;
                think(phil.number); //Думаем
                if(n==1)
                {
                    
                    take_left_fork(phil.number);        //Берем вилки случайно
                    take_right_fork(phil.number);
                }
                else
                {
                    take_right_fork(phil.number);
                    take_left_fork(phil.number);
                }
                if(test_fork(phil.number)==1)
                    eat(phil.number);
            }
            else
                if(phil.algorithm==2)   //Берем обе вилки
                {
                    think(phil.number);     //Думаем
                    take_forks(phil.number);//Берем вилки   
                    eat(phil.number);       //Едим
                }
        //кладем вилки
        if(phil.algorithm==0&&forks[phil.number].left==1&&forks[phil.number].right==1)
        {
            put_left_fork(phil.number);     //Кладем левую
            put_right_fork(phil.number);    //и правую по первому алгоритму
        }
        else    //Кладем вилки по второму алгоритму 
            if(phil.algorithm==1&&forks[phil.number].left==1&&forks[phil.number].right==1)
            {
                int n=rand()%2;
                if(n==1)
                {
                    put_left_fork(phil.number);
                    put_right_fork(phil.number);
                }
                else    //Случайным образом
                {
                    put_right_fork(phil.number);
                    put_left_fork(phil.number);
                }
            }
            else
                if(phil.algorithm==2)   //Кладем вилки по третьему алгоритму
                    put_forks(phil.number);
        
        Sleep(10);  //Даем время на переключение контекста
    }
}   
int main()  
{   
    srand(time(NULL));  //Что бы числа были действительно случайными
    Philosopher phil[N];
    for(int i=0; i<N; i++)  //Первоначально у философов нет вилок
    {
        forks[i].left=0;
        forks[i].right=0;
    }
    cout<<"Please input number of algorithm(0-left, 1-random, 2-right: "<<endl;
    for(int i=0; i<N; i++)  //Задаем алгоритмы взятия вилок
    {
        phil[i].number=i;
        cout<<"Philosopher number "<<phil[i].number<<": ";
        cin>>phil[i].algorithm;
    }
    for(int i=0; i<N; i++)  //Создаем мьютексы
    {
        philMutex[i] = CreateMutex( NULL, FALSE, NULL );
        forkMutex[i] = CreateMutex(NULL, FALSE, NULL);
    }
    InitializeCriticalSection( &cs );       //Инициализируем
    InitializeCriticalSection( &cs_forks ); //критические секции
    
    DWORD id[N];        //Идентификаторы потоков
    HANDLE hThread[N];  //Потоки
    for(int i=0; i<N; i++)//Создаем потоки
    {
        hThread[i] = CreateThread(NULL, NULL, &philosopher, &phil[i], NULL, &id[i]);    
        
    }
    Sleep(INFINITE);    //Чтобы потоки успели выполнится с корректными значениями 
    while(1);
}
он решает проблему самоблокировки, но не решает что философы могут питаться только через одного.
KpeHDeJIb
56 / 56 / 3
Регистрация: 31.10.2010
Сообщений: 103
05.11.2010, 18:57     Обедающие философы #11
Цитата Сообщение от programmerC++ Посмотреть сообщение
KpeHDeJIb, смотрите философы не могут есть вечно, кто то из них по ест и положит вилку следовательно другой начнет есть.
Не совсем так, возможен вариант когда все пять философов сядут одновременно и возьмут правую вилку, соответственно левой вилки ни у кого уже быть не может. Все, тупик.

Я понимаю еще программу которая вносит в эту задачу дополнительный механизм блокировки, но программу по самой задаче писать никакого смысла нету.
programmerC++
3 / 3 / 1
Регистрация: 04.11.2010
Сообщений: 38
05.11.2010, 19:03  [ТС]     Обедающие философы #12
Поэтому мне нужно решение.
KpeHDeJIb
56 / 56 / 3
Регистрация: 31.10.2010
Сообщений: 103
05.11.2010, 19:15     Обедающие философы #13
Цитата Сообщение от programmerC++ Посмотреть сообщение
Поэтому мне нужно решение.
К примеру можно ввести дополнительную CS которая не даст одновременно всем философам взять правую вилку, достаточно будет InterlockedCompareExchange и сравнения на кол-во берущих в данный момент вилку, если их количество 4, то не давать брать пятому вилку хотя бы в течении секунды (Sleep(1000) в потоке), а потом снова проверять. Это должно решить проблему.
programmerC++
3 / 3 / 1
Регистрация: 04.11.2010
Сообщений: 38
05.11.2010, 19:27  [ТС]     Обедающие философы #14
К примеру можно ввести дополнительную CS которая не даст одновременно всем философам взять правую вилку, достаточно будет InterlockedCompareExchange и сравнения на кол-во берущих в данный момент вилку, если их количество 4, то не давать брать пятому вилку хотя бы в течении секунды (Sleep(1000) в потоке), а потом снова проверять. Это должно решить проблему.
не понимаю идею...покажите на коде.
KpeHDeJIb
56 / 56 / 3
Регистрация: 31.10.2010
Сообщений: 103
05.11.2010, 19:57     Обедающие философы #15
Цитата Сообщение от programmerC++ Посмотреть сообщение
не понимаю идею...покажите на коде.
Идея простая, когда философ берет правую вилку то должен отрабатывать примерно такой код:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
while (true)
{
    LONG count = InterlockedIncrement(pPhilCount);
    if (count < 5)
        break;
 
    InterlockedDecrement(pPhilCount);
 
    // wait some time
    Sleep(1000);
}
 
// philospher eating
Sleep(10000);
 
InterlockedDecrement(pPhilCount);
PS. С InterlockedCompareExchange я немного погорячился, тут и без нее все просто.
programmerC++
3 / 3 / 1
Регистрация: 04.11.2010
Сообщений: 38
06.11.2010, 17:28  [ТС]     Обедающие философы #16
KpeHDeJIb, а можно увидеть целиком?)

Добавлено через 21 час 20 минут
нашел в сети но VS2010 не компилит
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
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
#include <iostream>
#include<time.h>
 
using namespace std;
 
 static pthread_cond_t cond=PTHREAD_COND_INITIALIZER;//Uslovnaia peremennaia 
 
static pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;//Mutex
 
 
#define f 15 //Vremia na obed
#define f1 (rand() % 3 + 1) //Vremia na edu
#define f2 (rand() % 5 + 1)  //Vremia na besedu
 
 static int forks = 3; //Vilki
 
  static void *Filosof(void *no) 
   { 
     int t=f;
    unsigned int t1;
      while (t > 0) { /* OBED */
         cout<<endl<<" Filosof "<<(int)no<<" beseduet!";
        t1 = (rand() % 5 + 1); 
        sleep (t1); 
        t -= t1;
        // Filosof pitaetsia vziat vilki
 
        pthread_mutex_lock (&mutex);
 
        while (forks == 0 )
        { cout<<endl<<"Filosof "<<(int)no<<" jdet!";
          pthread_cond_wait(&cond, &mutex);
        }
        cout<<"Filosof "<<(int)no<<" vzial vilki!";
        forks -= 1;
        pthread_mutex_unlock (&mutex);
 
        cout<<endl<<"Filosof "<<(int)no<<" est!";
        
        t1 = (rand() % 3 + 1);
        sleep (t1);
        t -= t1;
 
        pthread_mutex_lock (&mutex);
        
        forks +=1;
        pthread_cond_broadcast(&cond);
        pthread_mutex_unlock(&mutex);
    } /* while */
        cout<<endl<<" Filosof "<<(int)no<<" Vishel iz za     stola";    
    }
   
 
  int main()
   {  pthread_t tid;
      int i;
      int n=5;
    for(i=1; i<=n; i++)
     { 
     pthread_create(&tid, NULL, Filosof, (void*)i);
    } 
    }
1>c:\documents and settings\user\мои документы\visual studio 2010\projects\er\er\oloo.cpp(2): fatal error C1083: Cannot open include file: 'pthread.h': No such file or directory
silent_1991
Эксперт С++
4958 / 3034 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
06.11.2010, 17:33     Обедающие философы #17
Это вроде для gcc, pthread - линёвская фишка. В винде по-моему нити иначе создаются, поэтому и файл заголовочный, и функции другие нужны...
programmerC++
3 / 3 / 1
Регистрация: 04.11.2010
Сообщений: 38
07.11.2010, 12:29  [ТС]     Обедающие философы #18
silent_1991, то есть она будет работать на Linux а не на виндвозе?

Добавлено через 15 часов 59 минут
Как тогда данный код переписать под Windows?

Добавлено через 2 часа 54 минуты
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
#define N 5
/* Global Structures  */
typedef struct {
    int chopstick;
    int eating;
}
 
PHIL;
PHIL philAry [N];
PHIL philWait [N];
 
void think (int i);
void eat (int i);
void waitLeft (int i);
void waitRight (int i);
void check (int i);
void finish (int i);
void get_hungry_and_try_to_eat (int philoNo, int totalPhilo);
void philosopher (int amount);
void running(int waitTime);
 
void think (int i) {
    printf ("\nPhilosopher no. %d is hungry...\n", i);
}
 
void eat (int i) {
    printf ("\nPhilosopher no. %d is eating...\n", i);
    running (rand());
}
 
void finish (int i) {
    printf ("\nPhilosopher no. %d stops eating ", i);
    printf ("and releases chopsticks...\n");
    philAry[i].eating = 0;          // Philosopher stops eating
    philAry[i+1].chopstick = 1;     // Right philosopher takes back chopstick
    philAry[i-1].chopstick = 1;     // Left philosopher takes back chopstick
}
 
void waitLeft (int i) {
    printf ("\nLeft chopstick is not available, so ");
    printf ("philosopher no. %d has to wait...\n", i);
    philWait[i + 1].chopstick = 0;
}
 
void waitRight (int i) {
    printf ("\nRight chopstick is not available, so ");
    printf ("philosopher no. %d has to wait...\n", i);
    philWait[i].chopstick = 0;
}
 
void check (int i) {
    for (int count = 0; count < i; count ++) {
        if (!philWait[count].chopstick && philAry[count].chopstick) {
            printf ("\nPhilosopher no. %d gets both chopsticks.", i - 1);
            eat (i - 1);
            finish (i - 1);
            philWait[count].chopstick = 1;
        }
    }
}
 
void get_hungry_and_try_to_eat (int philoNo, int totalPhilo) {
 
    int left;
    int right;
 
    left = philoNo - 1;
    right = philoNo + 1;
 
    if (left < 0)
        left = totalPhilo;
 
    else if (right > totalPhilo)
        right = 0;
 
    if ((philAry[left].chopstick) && (!philAry[left].eating)) {
        printf ("\nPhilosopher no. %d gets left chopstick...", philoNo);
        philAry[left].chopstick = 0;
 
        if ((philAry[right].chopstick) && (!philAry[left].eating)){
            printf ("\nPhilosopher no. %d gets right chopstick...", philoNo);
            philAry[right].chopstick = 0;
            philAry[philoNo].eating = 1;        // philosopher is eating
            eat (philoNo);          
            finish (philoNo);
            philAry[left].chopstick = 1;        // Left philosopher takes back chopstick
            philAry[right].chopstick = 1;       // Right philosopher takes back chopstick
        }
 
        else {
            waitRight (philoNo);
            philAry[philoNo].eating = 0;
        }
    }
 
    else {
        waitLeft (philoNo);
        philAry[philoNo].eating = 0;
    }
}
 
void philosopher (int amount) {
    int randPhilo;
    int count = amount;
    while (count > 0) {
        running (rand());
        randPhilo = rand() % amount;
        think (randPhilo);
        check (amount);
        get_hungry_and_try_to_eat (randPhilo, amount);
        count--;
    }
    check (amount);
    printf ("\n");
}
 
void running(int waitTime)
{
    clock_t Goal;
    Goal=CLOCKS_PER_SEC*waitTime/1000+clock();
    while(Goal>clock());
}
 
void main () {
    int total, count;
    printf ("How many philosophers are eating?\n\n>>  ");
    scanf ("%d", &total);
    if (total != 0) {
        for (count = 0; count < total; count++) {
            philAry[count].chopstick = 1;
            philWait[count].chopstick = 1;
            philAry[count].eating = 0;
        }
        philosopher (total);
    }
    else {
        printf ("There is no any philosopher eating.\n\n");
    }   
}
Кому не сложно переделайте его на Семафоры и мониторы. =)
Yandex
Объявления
07.11.2010, 12:29     Обедающие философы
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru