You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The select case mechanism in Go Language is an important feature for concurrent programming.
I have tried to understand how the control flow works behind the scene, and adding the step by step execution trail here. I am still trying to understand it, so I will keep updating this as I know more.
There are various steps involved in executing a select block:
Evaluate all the channels involved and all the values that will be sent, from top to bottom and then left to right.
The orders of all the cases for polling are randomized, except for the default case. The default case branch is always put at the last position. It is possible that there are duplicate channels across the cases and orders.
All the involved channels are sorted to avoid deadlock. The first N channels of the sorted result contains all distinct channels (no duplicates). N is the number of involved channels in the select block.
All the channels involved are sorted by the sorted lock orders in the previous step.
Each case in the select block is now polled using a randomized case order, and one of the following actions is taken:
If the operation on the channel results into is sending a value to a closed channel, unlock all channels and panic. Finish.
If the operation on the channel is not blocked:
Perform the channel operation and unlock all channels.
Execute the body of the case, as mentioned in the block. The channel operation might call a blocked go-routine. Finish.
If the case is the default branch: unlock all the channels and execute the body fo default case. Finish.
For each case : push the current go-routine along with the operation involved for that case into the receiving or sending go-routine queue of the involved channel. The current go-routine may be pushed into the queues of the same channel multiple times, in case there are different cases that involve the same channel.
The current go-routine is blocked and all channels are unlocked in the sorted lock orders.
The current go-routine is in blocked status waiting for any of the channel operations to unblock it.
The current go-routine is woken up by a channel operation in another go-routine. The other operation could be one of the following:
A channel close operation.
A channel send/receive operation.
If it is a channel send/receive operation there has to be a case defined in the select block associated with that operation. During the execution of this operation: the current go-routine will be dequeued from the send/receive go-routine queue of the channel.
All involved channels are locked again according to the sorted lock orders.
The current go-routine is dequeued from the send/receive go-routine queue of the involved channel in each case operation and of the following events happens:
1. If the current go-routine is woken up by a channel close operation, go back to step 5. (I am not completely sure about this step, need to verify this further).
2. If the current go-routine is woken up by a channel send/receive operation, the corresponding case of the appropriate send/receive operation has already been discovered in the dequeuing process, so now all the channels are unlocked in the sorted lock orders and the case body of the corresponding case is executed.
The text was updated successfully, but these errors were encountered:
The select case mechanism in Go Language is an important feature for concurrent programming.
I have tried to understand how the control flow works behind the scene, and adding the step by step execution trail here. I am still trying to understand it, so I will keep updating this as I know more.
There are various steps involved in executing a
select
block:default
case. Thedefault
case branch is always put at the last position. It is possible that there are duplicate channels across the cases and orders.N
channels of the sorted result contains all distinct channels (no duplicates).N
is the number of involved channels in the select block.select
block is now polled using a randomized case order, and one of the following actions is taken:default
branch: unlock all the channels and execute the body fodefault
case. Finish.If it is a channel send/receive operation there has to be a case defined in the
select
block associated with that operation. During the execution of this operation: the current go-routine will be dequeued from the send/receive go-routine queue of the channel.1. If the current go-routine is woken up by a channel close operation, go back to step 5. (I am not completely sure about this step, need to verify this further).
2. If the current go-routine is woken up by a channel send/receive operation, the corresponding case of the appropriate send/receive operation has already been discovered in the dequeuing process, so now all the channels are unlocked in the sorted lock orders and the case body of the corresponding case is executed.
The text was updated successfully, but these errors were encountered: