fork download
  1. using System;
  2. using System.Threading;
  3.  
  4. public class Test
  5. {
  6. static void Main()
  7. {
  8. new Train(true);
  9. new Train(true);
  10. Thread.Sleep(100);
  11. new Train(false);
  12. new Train(true);
  13. new Train(false);
  14. Console.Read();
  15. }
  16. }
  17.  
  18. class Railway
  19. {
  20. public static Semaphore lock1 = new Semaphore(1, 1);
  21. }
  22.  
  23. class Train
  24. {
  25. static Semaphore w_turnstile = new Semaphore(1, 1);
  26. static Semaphore w_mutex = new Semaphore(1, 1);
  27. static int w_counter = 0;
  28. static Semaphore e_turnstile = new Semaphore(1, 1);
  29. static Semaphore e_mutex = new Semaphore(1, 1);
  30. static int e_counter = 0;
  31.  
  32. bool West;
  33. public Thread Thrd;
  34.  
  35. public Train(bool west)
  36. {
  37. West = west;
  38. Thrd = new Thread(this.Run);
  39. Thrd.Name = west ? "запад" : "восток";
  40. Thrd.Start();
  41. }
  42.  
  43. private Semaphore turnstile { get { return West ? w_turnstile : e_turnstile; } }
  44. private Semaphore turnstile2 { get { return West ? e_turnstile : w_turnstile; } }
  45. private Semaphore mutex { get { return West ? w_mutex : e_mutex; } }
  46. private int counter { get { return West ? w_counter : e_counter; } }
  47.  
  48. private void Inc()
  49. {
  50. if(West) w_counter++; else e_counter++;
  51. }
  52.  
  53. private void Dec()
  54. {
  55. if(West) w_counter--; else e_counter--;
  56. }
  57.  
  58.  
  59. void Run()
  60. {
  61. Console.WriteLine("- Подошёл поезд на {0}", Thrd.Name);
  62.  
  63. turnstile.WaitOne();
  64. turnstile.Release();
  65.  
  66. mutex.WaitOne();
  67. Inc();
  68. if(counter == 1)
  69. {
  70. turnstile2.WaitOne();
  71. Railway.lock1.WaitOne();
  72. Console.WriteLine("! Стрелка на {0}", Thrd.Name);
  73. turnstile2.Release();
  74. }
  75. mutex.Release();
  76.  
  77. //движение поезда
  78. Console.WriteLine("( Едет поезд на {0} ({1})", Thrd.Name, counter);
  79. Thread.Sleep(1000);
  80.  
  81. mutex.WaitOne();
  82. Dec();
  83. if(counter == 0)
  84. {
  85. Railway.lock1.Release();
  86. }
  87. mutex.Release();
  88. Console.WriteLine(") Проехал поезд на {0} ({1})", Thrd.Name, counter);
  89. }
  90. }
Success #stdin #stdout 0.07s 34024KB
stdin
Standard input is empty
stdout
- Подошёл поезд на запад
- Подошёл поезд на запад
! Стрелка на запад
( Едет поезд на запад (1)
( Едет поезд на запад (2)
- Подошёл поезд на восток
- Подошёл поезд на запад
- Подошёл поезд на восток
) Проехал поезд на запад  (1)
) Проехал поезд на запад  (0)
! Стрелка на восток
( Едет поезд на восток (1)
( Едет поезд на восток (2)
) Проехал поезд на восток  (1)
) Проехал поезд на восток  (0)
! Стрелка на запад
( Едет поезд на запад (1)
) Проехал поезд на запад  (0)