I wanted to ask if are there any articles about threading in Nim 2
In particular, I am interested in data sharing between threads Can I move data between threads without copying it? I remember there was some Isolated stuff, but it was in development
And some stuff about SharedPtr. Are there any articles or examples of how to use it?
For me, real multithreading without unsafe ptrs is a deal breaker
Here is an example showing list handling via Isolated[T]:
import std / [os, locks, atomics, isolation]
type
MyList {.acyclic.} = ref object
data: string
next: Isolated[MyList]
template withMyLock*(a: Lock, body: untyped) =
acquire(a)
{.gcsafe.}:
try:
body
finally:
release(a)
var head: Isolated[MyList]
var headL: Lock
var shouldStop: Atomic[bool]
initLock headL
proc send(x: sink string) =
withMyLock headL:
head = isolate MyList(data: x, next: move head)
proc worker() {.thread.} =
var workItem = MyList(nil)
var echoed = 0
while true:
withMyLock headL:
var h = extract head
if h != nil:
workItem = h
# workitem is now isolated:
head = move h.next
else:
workItem = nil
# workItem is isolated, so we can access it outside
# the lock:
if workItem.isNil:
if shouldStop.load:
break
else:
# give producer time to breath:
os.sleep 30
else:
if echoed < 100:
echo workItem.data
inc echoed
var thr: Thread[void]
createThread(thr, worker)
send "abc"
send "def"
for i in 0 ..< 10_000:
send "xzy"
send "zzz"
shouldStop.store true
joinThread(thr)
But it's unlikely to be particularly useful unless you think linked lists are a good idea.
Here is a more interesting program:
import std / [strutils, tables]
import malebolgia
import malebolgia / ticketlocks
proc countWords(filename: string; results: ptr CountTable[string]; L: ptr TicketLock) =
for w in splitWhitespace(readFile(filename)):
withLock L[]:
results[].inc w
proc main =
var m = createMaster()
var results = initCountTable[string]()
var L = initTicketLock() # protects `results`
m.awaitAll:
m.spawn countWords("temp.nim", addr results, addr L)
m.spawn countWords("tester.nim", addr results, addr L)
results.sort()
echo results
main()