zolern (6) [Avatar] Offline
I have suggestion about more complex implementation; channels are so nice instrument in concurrent programming and deserve to be presented with a good and interesting code example.

Here it is my idea:

import threadpool

  MessageType = enum
    mtStart, mtIncrement, mtStopThread
  Message = tuple[msgType: MessageType, msgValue: int]

var actionChannel: Channel[Message]
open actionChannel

proc increment(count: int) =
  var increment = 0

  for _ in 1 .. count:
    if actionChannel.ready:
      actionChannel.send((mtIncrement, increment))
      increment = 0

  actionChannel.send((mtStopThread, increment))

proc counting(): int =
  var threadsCount = 0
  while true:
    let (msg, value) = actionChannel.recv

    case msg:
    of mtStart:
      threadsCount = value

    of mtIncrement:
      result += value
    of mtStopThread:
      result += value

      doAssert threadsCount > 0

      if threadsCount == 0:

let threadsCount = 10
actionChannel.send((mtStart, threadsCount))

for _ in 1 .. threadsCount:
  spawn increment(10_000_000)

let counter = spawn counting()


echo "Counter: ", ^counter

There are some interesting moments in this code example:

- channel content is tuple with message type and message value
- channel is used not only for counting, but also for threads management
- tricky conception how to save channel from intensive flooding (here 10 threads send messages but only one thread reads them)
dom96 (75) [Avatar] Offline
Thank you, but unfortunately Chapter 6 is already rather long so I don't think I will have space to make any of the examples there more complex.