Channel Synchronization in Nim

We can use channels to synchronize execution across threads. Here’s an example of using a blocking receive to wait for a thread to finish. When waiting for multiple threads to finish, you may prefer to use a CountdownLatch or ThreadPool.

import std/[threadpool, os]

# This is the procedure we'll run in a thread. The
# `done` channel will be used to notify another
# thread that this procedure's work is done.
proc worker(done: Channel[bool]) =
  stdout.write("working...")
  stdout.flushFile()
  sleep(1000) # Sleep for 1 second
  echo "done"

  # Send a value to notify that we're done.
  done.send(true)

# Start a worker thread, giving it the channel to
# notify on.
let done = newChannel[bool]()
spawn worker(done)

# Block until we receive a notification from the
# worker on the channel.
discard done.recv()

To run the program:

$ nim c -r channel_synchronization.nim
working...done

If you removed the discard done.recv() line from this program, the program would exit before the worker even started.

In Nim, we use spawn to create a new thread, which is similar to goroutines in concept. The Channel type is used for communication between threads, analogous to channels in Go. The newChannel[bool]() creates a new channel that can send and receive boolean values.

The worker procedure simulates work by sleeping for a second, and then sends a value on the channel to signal completion. The main thread waits for this signal by calling done.recv(), which blocks until a value is received.

Note that Nim’s concurrency model is based on OS threads, which are more heavyweight than Go’s goroutines, but the synchronization concept remains similar.

查看推荐产品

Comments powered by Disqus