423 Star 4.3K Fork 426

GVPPaddlePaddle / Paddle

 / 详情

Ideate on implementing the `Select` case in `Go`.

已完成
创建于  
2021-03-26 16:44

源自github用户kavyasrinet:
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:

  1. Evaluate all the channels involved and all the values that will be sent, from top to bottom and then left to right.
  2. 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.
  3. 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.
  4. All the channels involved are sorted by the sorted lock orders in the previous step.
  5. Each case in the select block is now polled using a randomized case order, and one of the following actions is taken:
    1. If the operation on the channel results into is sending a value to a closed channel, unlock all channels and panic. Finish.
    2. If the operation on the channel is not blocked:
      1. Perform the channel operation and unlock all channels.
      2. Execute the body of the case, as mentioned in the block. The channel operation might call a blocked go-routine. Finish.
    3. If the case is the default branch: unlock all the channels and execute the body fo default case. Finish.
  6. 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.
  7. The current go-routine is blocked and all channels are unlocked in the sorted lock orders.
  8. The current go-routine is in blocked status waiting for any of the channel operations to unblock it.
  9. The current go-routine is woken up by a channel operation in another go-routine. The other operation could be one of the following:
    1. A channel close operation.
    2. 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.
  10. All involved channels are locked again according to the sorted lock orders.
  11. 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.

评论 (0)

PaddlePaddle-Gardener 创建了任务
PaddlePaddle-Coordinator 任务状态待办的 修改为已完成
展开全部操作日志

登录 后才可以发表评论

状态
负责人
里程碑
Pull Requests
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
开始日期   -   截止日期
-
置顶选项
优先级
参与者(1)
Python
1
https://gitee.com/paddlepaddle/Paddle.git
git@gitee.com:paddlepaddle/Paddle.git
paddlepaddle
Paddle
Paddle

搜索帮助