fork(1) download
  1. Channel = {}
  2. Channel.__index = Channel
  3.  
  4. function Channel.new()
  5. self = {}
  6. setmetatable(self, Channel)
  7. self._senders = {}
  8. self._receivers = {}
  9. return self
  10. end
  11.  
  12. function Channel:send(value)
  13. if #self._receivers > 0 then
  14. receiver = table.remove(self._receivers, math.random(#self._receivers))
  15. coroutine.resume(receiver, value)
  16. else
  17. table.insert(self._senders, coroutine.running())
  18. coroutine.yield()
  19. coroutine.yield(value)
  20. end
  21. end
  22.  
  23. function Channel:receive()
  24. if #self._senders > 0 then
  25. sender = table.remove(self._senders, math.random(#self._senders))
  26. status, value = coroutine.resume(sender)
  27. return value
  28. else
  29. table.insert(self._receivers, coroutine.running())
  30. return coroutine.yield()
  31. end
  32. end
  33.  
  34. channel = Channel.new()
  35.  
  36. function test()
  37. co1 = coroutine.create(function()
  38. print("co1: Sending 1...")
  39. channel:send(1)
  40. print("co1: Sent 1!")
  41. end)
  42.  
  43. co2 = coroutine.create(function()
  44. print("co2: Sending 2...")
  45. channel:send(2)
  46. print("co2: Sent 2!")
  47. end)
  48.  
  49. co3 = coroutine.create(function()
  50. print("co3: Receiving...")
  51. value = channel:receive()
  52. print("co3: Received " .. value .. "!")
  53. end)
  54.  
  55. co4 = coroutine.create(function()
  56. print("co4: Receiving...")
  57. value = channel:receive()
  58. print("co4: Received " .. value .. "!")
  59. end)
  60.  
  61. return co1, co2, co3, co4
  62. end
  63.  
  64. print("Scenario 1: send, then receive")
  65. co1, co2, co3, co4 = test()
  66. coroutine.resume(co1)
  67. coroutine.resume(co2)
  68. coroutine.resume(co1)
  69. coroutine.resume(co2)
  70.  
  71. print("Scenario 2: receive, then send")
  72. co1, co2, co3, co4 = test()
  73. coroutine.resume(co3)
  74. coroutine.resume(co1)
  75. coroutine.resume(co3)
  76. coroutine.resume(co1)
  77.  
  78. print("Scenario 3: receive, receive, then send")
  79. co1, co2, co3, co4 = test()
  80. coroutine.resume(co3)
  81. coroutine.resume(co4)
  82. coroutine.resume(co1)
  83. coroutine.resume(co3)
  84. coroutine.resume(co4)
  85. coroutine.resume(co1)
  86.  
  87. print("Scenario 4: send, receive, then receive")
  88. co1, co2, co3, co4 = test()
  89. coroutine.resume(co1)
  90. coroutine.resume(co3)
  91. coroutine.resume(co4)
  92. coroutine.resume(co1)
  93. coroutine.resume(co3)
  94. coroutine.resume(co4)
  95.  
  96. print("Scenario 5: send, send, receive, then receive")
  97. co1, co2, co3, co4 = test()
  98. coroutine.resume(co1)
  99. coroutine.resume(co2)
  100. coroutine.resume(co3)
  101. coroutine.resume(co4)
  102. coroutine.resume(co1)
  103. coroutine.resume(co2)
  104. coroutine.resume(co3)
  105. coroutine.resume(co4)
  106.  
  107. print("Scenario 6: receive, receive, send, then send")
  108. co1, co2, co3, co4 = test()
  109. coroutine.resume(co3)
  110. coroutine.resume(co4)
  111. coroutine.resume(co1)
  112. coroutine.resume(co2)
  113. coroutine.resume(co3)
  114. coroutine.resume(co4)
  115. coroutine.resume(co1)
  116. coroutine.resume(co2)
  117.  
Success #stdin #stdout 0.01s 2496KB
stdin
Standard input is empty
stdout
Scenario 1: send, then receive
co1: Sending 1...
co2: Sending 2...
Scenario 2: receive, then send
co3: Receiving...
co2: Sent 2!
co1: Sending 1...
Scenario 3: receive, receive, then send
co3: Receiving...
co1: Sent 1!
co4: Receiving...
co1: Sent 1!
co1: Sending 1...
Scenario 4: send, receive, then receive
co1: Sending 1...
co3: Receiving...
co3: Received 1!
co4: Receiving...
co1: Sent 1!
co1: Sent 1!
Scenario 5: send, send, receive, then receive
co1: Sending 1...
co2: Sending 2...
co3: Receiving...
co3: Received 1!
co4: Receiving...
co4: Received 2!
co1: Sent 1!
co2: Sent 2!
Scenario 6: receive, receive, send, then send
co3: Receiving...
co4: Receiving...
co1: Sending 1...
co4: Received 1!
co1: Sent 1!
co2: Sending 2...
co3: Received 2!
co2: Sent 2!