Sorry for one more question, but, I'm trying to pass a channel to a spawned function. But at the end of the compilation it says that the expression 'chan' is immutable, not 'var'! Does anyone know the correct way to pass a channel to a spawned function?
import threadpool
proc myTest(chan: Channel[string], s: string): int =
echo s
let word = chan.recv()
echo word
return word.len
proc main() =
var chan: Channel[string]
chan.open()
let x = ^spawn myTest(chan, "Worker 1")
let y = ^spawn myTest(chan, "Worker 2")
chan.send("Hello World!")
sync()
chan.close()
let z = x + y
echo $z
main()
Error message:
/home/hdias/devel/test.nim(7, 18) Error: type mismatch: got <Channel[system.string]>
but expected one of:
proc recv[TMsg](c: var Channel[TMsg]): TMsg
first type mismatch at position: 1
required type for c: var Channel[recv.TMsg]
but expression 'chan' is immutable, not 'var'
expression: recv(chan)
proc myTest(chan: var Channel[string], s: string): int =
echo s
let word = chan.recv()
echo word
return word.len
Add var to the patameter https://nim-lang.org/docs/manual.html#proceduresThanks, @ynfle. But, unfortunately it doesn't work.
/home/hdias/devel/test.nim(14, 25) Error: 'spawn'ed function cannot have a 'var' parameter
Note: Channels cannot be passed between threads. Use globals or pass them by ptr
You need to manually allocate them into the shared heap if you don't want to declare the channel as a global. For example...
import threadpool
proc myTest(chan: ptr Channel[string], s: string): int =
echo s
let word = chan[].recv()
echo word
return word.len
proc main() =
let chan = cast[ptr Channel[string]](
allocShared0(sizeof(Channel[string]))
)
chan[].open()
let x = ^spawn myTest(chan, "Worker 1")
let y = ^spawn myTest(chan, "Worker 2")
chan[].send("Hello World!")
sync()
chan[].close()
deallocShared(chan)
let z = x + y
echo $z
main()
Thanks @sekao. It's a bit complicated, but works! It could be simpler, but, anyway it's amazing :-) This is what I intended to do:
import threadpool
import os
import strutils
proc myTest(chan: ptr Channel[string], s: string): int =
echo s
chan[].send(s)
return s.len
proc myRecv(chan: ptr Channel[string]) =
var myWorkers: seq[string]
while true:
let tried = chan[].tryRecv()
if tried.dataAvailable:
if tried.msg == "END":
echo "Goodbye " & myWorkers.join(", ")
break
myWorkers.add(tried.msg)
echo "Hello ", tried.msg
sleep(400)
proc main() =
var chan = cast[ptr Channel[string]](
allocShared0(sizeof(Channel[string]))
)
chan[].open()
spawn myRecv(chan)
let x = ^spawn myTest(chan, "First Worker")
let y = ^spawn myTest(chan, "Second Worker")
chan[].send("END")
sync()
chan[].close()
chan.deallocShared()
let z = x + y
echo $z
main()