Hi everyone. I’m trying to learn how to use threads in Julia by comparing them to the Python examples from Ramalho’s Fluent Python book Fluent Python, 2nd Edition [Book].
The basic Python example is:
import itertools
import time
from threading import Thread, Event
def spin(msg: str, done: Event) -> None:
for char in itertools.cycle(r'\|/-'):
status = f'\r{char} {msg}'
print(status, end='', flush=True)
# returns False after s and keep looping
# or if another treat calls Event.set(), return True and break loop
if done.wait(.1):
break
blanks = ' ' * len(status)
print(f'\r{blanks}\r', end='')
def slow() -> int:
# blocks main thread, but releases GIL, so other threads can run
time.sleep(3)
# long function finishes
return 42
def supervisor() -> int:
done = Event() # starts as False
spinner = Thread(target=spin, args=('thinking!', done))
print(f'spinner object: {spinner}')
spinner.start() # start spin thread
result = slow() # blocks main thread
done.set() # spin loop will end
spinner.join() # wait for spin thread to end
return result
supervisor()
I have a Julia implementation as (started Julia with 4 threads):
using Base.Threads
function spin(msg::String, done::Threads.Atomic{Bool})
for char in Iterators.cycle("\\|/-")
status = "\r$(char) $(msg)"
print(status)
flush(stdout)
sleep(0.1)
if done[]
break
end
end
blanks = " " ^ (length(msg)+3)
print("\r$(blanks)\r")
end
function slow()
sleep(3)
return 42
end
function supervisor()
done = Threads.Atomic{Bool}(false);
spinner = Threads.@spawn spin("thinking!", done)
println("spinner object: $(spinner)")
result = slow()
done[] = true
wait(spinner)
return result
end
supervisor()
My question is twofold. First is this an idiomatic or Julian way to use Threads.Atomic? Secondly, could someone suggest how to accomplish this with Event or Condition? I found the documentation for those 2 types hard to follow. Thanks everyone.