1
- namespace _2022 . _08 . _31_PW
1
+ //Решение заключается в ограничении количества человек, которые могут подойти к месту, где лежат вилки. Это решение уходит
2
+ //от максималньного быстродействия, но гарантирует, что все философы рано или поздно смогут поесть.
3
+
4
+ namespace _2022 . _08 . _31_PW
2
5
{
3
6
internal class Program
4
7
{
5
- static Semaphore semaphore = new ( 2 , 2 ) ;
8
+ static object locker = new ( ) ;
6
9
static List < Fork > forks = new ( ) { new ( ) , new ( ) , new ( ) , new ( ) , new ( ) } ;
7
10
static List < Philosopher > philosophers = new ( )
8
11
{
@@ -16,59 +19,61 @@ internal class Program
16
19
static void Main ( )
17
20
{
18
21
Task . Run ( ExitWait ) ;
22
+ List < Task > tasksCycles = new ( ) ;
23
+ foreach ( Philosopher philosopher in philosophers )
24
+ {
25
+ tasksCycles . Add ( new ( ( ) => Cycle ( philosopher ) ) ) ;
26
+ }
27
+ foreach ( Task task in tasksCycles )
28
+ {
29
+ task . Start ( ) ;
30
+ }
31
+ Task . WaitAll ( tasksCycles . ToArray ( ) ) ;
32
+ }
33
+
34
+ static void Cycle ( Philosopher philosopher )
35
+ {
19
36
while ( true )
20
37
{
21
- List < Task > tasks = new ( ) ;
22
- semaphore . WaitOne ( ) ;
23
- foreach ( Philosopher philosopher in philosophers )
38
+ philosopher . Thinking ( ) ;
39
+ bool goEat = false ;
40
+ Fork leftFork = null ;
41
+ Fork rightFork = null ;
42
+ lock ( locker ) //К выдаче вилок подходит может подойти только 1 человек!
24
43
{
25
- Fork fork1 = null ;
26
- Fork fork2 = null ;
27
- for ( int i = 0 ; i < forks . Count ; i ++ )
28
- {
29
- if ( ! forks [ i ] . IsBusy )
30
- {
31
- fork1 = forks [ i ] ;
32
- break ;
33
- }
34
- }
35
- for ( int i = 0 ; i < forks . Count ; i ++ )
44
+ foreach ( Fork fork1 in forks ) //Ищем первую вилку
36
45
{
37
- if ( ! forks [ i ] . IsBusy )
46
+ if ( ! fork1 . IsBusy ) //Если есть свободная вилка
38
47
{
39
- fork2 = forks [ i ] ;
48
+ fork1 . IsBusy = true ; //Берём её
49
+ foreach ( Fork fork2 in forks ) //Ищем вторую вилку
50
+ {
51
+ if ( ! fork2 . IsBusy ) //Если есть свободная вилка
52
+ {
53
+ fork2 . IsBusy = true ; //Берём её
54
+ goEat = true ; //Идём кушать
55
+ leftFork = fork1 ;
56
+ rightFork = fork2 ;
57
+ break ;
58
+ }
59
+ }
60
+ fork1 . IsBusy = false ; //Если не была найдена вторая вилка - ложим вилку и останавливаем цикл
40
61
break ;
41
62
}
42
63
}
43
- if ( fork1 != null && fork2 != null )
44
- {
45
- tasks . Add ( Task . Run ( ( ) => Cycle ( philosopher , fork1 , fork2 ) ) ) ;
46
- }
47
64
}
48
- Task . WaitAll ( tasks . ToArray ( ) ) ;
49
- semaphore . Release ( ) ;
65
+ if ( goEat ) //А вот кушать за общим столом могут все вместе!
66
+ {
67
+ philosopher . Eating ( leftFork , rightFork ) ; //Вилки ложаться обратно внутри класса
68
+ }
50
69
}
51
70
}
52
71
53
- static void Cycle ( Philosopher philosopher , Fork fork1 , Fork fork2 )
54
- {
55
- Console . WriteLine ( $ "Философ { philosopher . Name } думает") ;
56
- philosopher . Thinking ( ) ;
57
- fork1 . IsBusy = true ;
58
- fork2 . IsBusy = true ;
59
- Console . WriteLine ( $ "Философ { philosopher . Name } кушает") ;
60
- philosopher . Eating ( ) ;
61
- fork1 . IsBusy = false ;
62
- fork2 . IsBusy = false ;
63
- Console . WriteLine ( $ "Философ { philosopher . Name } думает") ;
64
- philosopher . Thinking ( ) ;
65
- }
66
-
67
72
static void ExitWait ( )
68
73
{
69
74
while ( true )
70
75
{
71
- if ( Console . ReadKey ( ) . Key == ConsoleKey . Q )
76
+ if ( Console . ReadKey ( ) . Key == ConsoleKey . End )
72
77
{
73
78
Environment . Exit ( 0 ) ;
74
79
}
0 commit comments