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