В небуферизованном канале запись в канал не произойдет до тех пор, пока не появится какой-то приемник, который ожидает получения данных, что означает в приведенном ниже примере
func main(){
ch := make(chan int)
ch <- 10 /* Main routine is Blocked, because there is no routine to receive the value */
<- ch
}
Теперь, если у нас есть другая процедура го, применяется тот же принцип.
func main(){
ch :=make(chan int)
go task(ch)
ch <-10
}
func task(ch chan int){
<- ch
}
Это будет работать, потому что процедура task ожидает использования данных до того, как произойдет запись в небуферизованный канал.
Чтобы было понятнее, давайте поменяем порядок второго и третьего операторов в основной функции.
func main(){
ch := make(chan int)
ch <- 10 /*Blocked: No routine is waiting for the data to be consumed from the channel */
go task(ch)
}
Это приведет к тупику
Короче говоря, запись в небуферизованный канал происходит только тогда, когда есть какая-то процедура, ожидающая чтения из канала, иначе операция записи блокируется навсегда и приводит к тупиковой ситуации.
ПРИМЕЧАНИЕ: та же концепция применяется к буферизованному каналу, но отправитель не блокируется до тех пор, пока буфер не заполнится, что означает, что получатель не обязательно должен синхронизироваться с каждой операцией записи.
Итак, если у нас есть буферизованный канал размера 1, то ваш вышеупомянутый код будет работать
func main(){
ch := make(chan int, 1) /*channel of size 1 */
ch <-10 /* Not blocked: can put the value in channel buffer */
<- ch
}
Но если мы напишем больше значений в приведенный выше пример, то возникнет тупик.
func main(){
ch := make(chan int, 1) /*channel Buffer size 1 */
ch <- 10
ch <- 20 /*Blocked: Because Buffer size is already full and no one is waiting to recieve the Data from channel */
<- ch
<- ch
}
person
bharatj
schedule
17.12.2016