I want to use and test multi-threading with synchronization between them using channel channels
as in the example MWE, in which nthreads()=3
. Each thread executes for-loop
and while-loop
inside it.
In each iteration of the while-loop
, the first thread, i.e., threadid()=1
, put!
into channels
and blocks until threads 2&3
take!
. Then move to the next iteration. threadid()=1
also updates status
in the second iteration of the while-loop
to get out of it.
To track the execution of thread 1
, the command println("Iteration $t Thread $(threadid()) Update status")
is assigned it. While for threads 2&3
, the command println("Iteration $t Thread $(threadid()) Execution")
is assigned to them.
function f()
iter = 0 # artificial parameter that helps in updating `status`
channels = [Channel{Nothing}(0) for i in 1:(nthreads()-1)]
status = true
thrs = [@tspawnat i begin
for t in 1:2
iter = 0
status = true
while status
if threadid() == 1
#This is to reverse the value of `status` in the second iteration of the `while loop`
iter += 1;
if iter == 2
status = false
end
println("Iteration $t Thread $(threadid()) Update status")
#
put!.(channels, nothing)
else
take!(channels[threadid()-1])
println("Iteration $t Thread $(threadid()) Execution")
end # if threadid() == 1
end # while status
end # for t in 1:2
end for i = 1:nthreads()];
fetch.(thrs);
end
f()
I expect the results to be as below, however, it freezes randomly. I think it is due to improper usage of put!
and take!
for channels
. Could you please guide me to solve the problem?.
Iteration 1 Thread 1 Update status
Iteration 1 Thread 2 Execution
Iteration 1 Thread 3 Execution
Iteration 1 Thread 1 Update status
Iteration 1 Thread 2 Execution
Iteration 1 Thread 3 Execution
Iteration 2 Thread 1 Update status
Iteration 2 Thread 2 Execution
Iteration 2 Thread 3 Execution
Iteration 2 Thread 1 Update status
Iteration 2 Thread 2 Execution
Iteration 2 Thread 3 Execution