Playing with threads I found strange behaviour of _spawn_. I made a simple test
of multi-threading: there is the routine
proc multithreadedPrint(sMsg: string, nCount: int)
which prints the specified string _nCount_ number of times. And each character
of the string is printed by its own thread. So number of threads spawned is
equal to the length of the string provided (in Unicode characters).
And the strange behaviour is: when I spawn 8 or less threads (I tested on
4-cores CPU) all works just perfect, but when I spawn 9+ threads this app never
finishes.
import unicode, threadpool, locks, os
proc lenU*(s: string): int =
result = s.runeLen
proc charAtPosU*(s: string, pos: int): string =
assert(pos >= 0 and pos < s.runeLen)
result = s.runeAtPos(pos).toUTF8()
proc multithreadedPrint(sMsg: string, nCount: int) =
var
nLen = sMsg.lenU
nCallsTotal = 0
nCallsCur = 0
lk: Lock
res = 0
proc worker(c: string, value: int) {.gcsafe.}=
while true:
acquire(lk)
try:
if nCallsCur == nCallsTotal:
return
if res == value:
inc res
res = res mod nLen
inc nCallsCur
stdout.write c
else:
sleep(1)
finally:
release(lk)
if nLen > 0:
if nLen > MaxDistinguishedThread:
echo "Your string is too long. Maximum allowed is ",
MaxDistinguishedThread, "!"
return
setMinPoolSize(nLen)
setMaxPoolSize(nLen)
initLock(lk)
try:
nCallsTotal = nLen * nCount
echo("Total threads: ", nLen)
echo("Total calls: ", nCallsTotal)
for i in 0..<nLen:
spawn worker(sMsg.charAtPosU(i), i)
sync()
finally:
deinitLock(lk)
multithreadedPrint("0123456789", 2)