Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).
template once*(body: untyped): untyped =
var alreadyExecuted {.global.} = false
if not alreadyExecuted:
alreadyExecuted = true
body
[EDIT] Example
when defined caseSub:
const N = 10
var thr: array[N, Thread[int]]
var count = 0
proc threadFunc(a: int) {.thread.} =
once: count.inc
doAssert count == 1
proc main =
for i in 0..<N:
createThread(thr[i], threadFunc, i)
joinThreads(thr)
main()
else:
import os, strformat
proc main =
const nim = getCurrentCompilerExe()
const exe = "/tmp/z01b"
const file = currentSourcePath
# -d:danger
let cmd = fmt"{nim} c -d:caseSub --threads -o:{exe} {file}"
echo cmd
doAssert execShellCmd(cmd) == 0
for i in 0..<10000:
let ret = execShellCmd(exe)
doAssert ret == 0, $i
main()
Current output
fails after a few iterations: count == 1 [AssertionDefect]
system.once
isn't thread safe:[EDIT] Example
Current output
fails after a few iterations:
count == 1
[AssertionDefect]Expected output
works
see also