# Synchronizing 2 loops in multi-threading

What’s the best way to synchronize 2 while loops, each running on its own thread?

In the example below, loop1 runs 80 times per second while loop2 (blocking/IO) runs 20 times per second. Currently, without any locks/synchronizations, the timing of the loops diverges away as time passes.

timer1 = Timer(0, interval=1/80)
timer2 = Timer(0, interval=1/20)

function loop1()
wait(timer1)
while q_loop.value
wait(timer1)
end
end

function loop2()
wait(timer2)
while q_loop.value
# do a different task involving IO (blocking)
wait(timer2)
end
end

function loop()
@sync begin
end
end

# start and run the loops until the user requests to stop
q_loop.value = true
@async loop()

# stop the loops
q_loop.value = false

If the loops perform independent operations, then why do they need to be synchronized? If the are interdependent, synchonize by communicating (via a Channel).

1 Like

I’m not sure what all your constraints are but I feel like the easiest way to keep the two functions in lock step are to run them off of one timer like:

function loop1(ch1)
for _ in ch1
println("Quick")
end
end

function loop2(ch2)
for _ in ch2
println("Slow")
end
end

function loop()
ch1 = Channel{Bool}(16)
ch2 = Channel{Bool}(16)
q_loop[] = true

@async begin
sleep(2)
q_loop[] = false
end

@sync begin

local c = 1
Timer(0, interval=1/80) do t
if q_loop[] == false
close(ch1)
close(ch2)
close(t)
elseif c == 4
put!(ch1, true)
put!(ch2, true)
c = 1
else
put!(ch1, true)
c += 1
end
end
end

end

Here you have 1 timer that runs at 1/80 which wakes up loop1() every tick and loop2() every 4th tick. The channels of size 16 give you a little bit of slop if loop1() takes over 1/80 a second to perform it’s operation or loop2() takes over 1/20 to do it’s thing. However if either loops takes longer consistently you are going to have a general slow down.

You could resolve this by checking the channels before putting true into them, if they are full generate some sort of alert. You could also replace the Channels with Events in which case if either loop takes to long it will just “miss” the next tick.