**@wiffel, @Araq:** Thanks a lot! I really missed that it's impossible to use spawn with closures. :(
So the sample should look like below one. It's much more verbose, but it works properly. import unicode, 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() type Container = ref ContainerObj ContainerObj = object of RootObj Flk: Lock FnLen: int FnCallsTotal: int FnCallsCur: int FnCallIndex: int WorkerThread = Thread[tuple[cont: Container, c: string, value: int]] proc newContainer(nLen, nCount: int): Container = result.new() result.Flk.initLock() result.FnLen = nLen result.FnCallsTotal = nLen*nCount result.FnCallsCur = 0 result.FnCallIndex = 0 proc isTimeToFinish(self: Container): bool = result = self.FnCallsCur == self.FnCallsTotal proc isOurCallIndex(self: Container, nCallIndex: int): bool = result = self.FnCallIndex == nCallIndex proc goToNextCallIndex(self: Container) = inc self.FnCallIndex self.FnCallIndex = self.FnCallIndex mod self.FnLen inc self.FnCallsCur proc destroyContainer(cont: var Container) = cont.Flk.deinitLock() cont = nil proc worker(param: tuple[cont: Container, c: string, value: int]) {.thread.} = while true: var bWorkDone = true param.cont.Flk.acquire() try: if param.cont.isTimeToFinish: return if param.cont.isOurCallIndex(param.value): param.cont.goToNextCallIndex() stdout.write param.c else: bWorkDone = false finally: param.cont.Flk.release() if not bWorkDone: sleep(1) proc multithreadedPrint(sMsg: string, nCount: int) = var cont = newContainer(sMsg.len, nCount) threads: seq[WorkerThread] = newSeq[WorkerThread](sMsg.len) for i in 0..<sMsg.len: threads[i].createThread(worker, (cont, sMsg.charAtPosU(i), i)) joinThreads(threads) destroyContainer(cont) multithreadedPrint("01234567890123456789", 3) echo ""