英文:
I don't understand the golang channel well
问题
close(e.ready)
and <-e.ready
are used to synchronize the goroutines in the memo
package.
In the code you provided, close(e.ready)
is called in the call
method of the entry
struct. This line of code is responsible for broadcasting the "ready" condition to all goroutines waiting on the e.ready
channel. By closing the channel, it indicates that the result is ready and any goroutine waiting on this channel can proceed.
On the other hand, <-e.ready
is called in the deliver
method of the entry
struct. This line of code is used to wait for the "ready" condition. When this line is executed, the goroutine will block until another goroutine closes the e.ready
channel. Once the channel is closed, the goroutine will continue executing and send the result to the client through the response
channel.
In summary, close(e.ready)
is used to signal that the result is ready, and <-e.ready
is used to wait for the result to be ready before proceeding. This synchronization mechanism ensures that the result is delivered to the client only when it is available.
英文:
Goroutines and channels are bothering me these days. I'm looking at the memo5 code at https://github.com/adonovan/gopl.io/tree/master/ch9.
If you look at memo.go of memo5, there are func (e *entry) call(f Func, key string)
and func (e *entry) deliver(response chan<- result)
parts.
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
// See page 278.
// Package memo provides a concurrency-safe non-blocking memoization
// of a function. Requests for different keys proceed in parallel.
// Concurrent requests for the same key block until the first completes.
// This implementation uses a monitor goroutine.
package memo
//!+Func
// Func is the type of the function to memoize.
type Func func(key string) (interface{}, error)
// A result is the result of calling a Func.
type result struct {
value interface{}
err error
}
type entry struct {
res result
ready chan struct{} // closed when res is ready
}
//!-Func
//!+get
// A request is a message requesting that the Func be applied to key.
type request struct {
key string
response chan<- result // the client wants a single result
}
type Memo struct{ requests chan request }
// New returns a memoization of f. Clients must subsequently call Close.
func New(f Func) *Memo {
memo := &Memo{requests: make(chan request)}
go memo.server(f)
return memo
}
func (memo *Memo) Get(key string) (interface{}, error) {
response := make(chan result)
memo.requests <- request{key, response}
res := <-response
return res.value, res.err
}
func (memo *Memo) Close() { close(memo.requests) }
//!-get
//!+monitor
func (memo *Memo) server(f Func) {
cache := make(map[string]*entry)
for req := range memo.requests {
e := cache[req.key]
if e == nil {
// This is the first request for this key.
e = &entry{ready: make(chan struct{})}
cache[req.key] = e
go e.call(f, req.key) // call f(key)
}
go e.deliver(req.response)
}
}
func (e *entry) call(f Func, key string) {
// Evaluate the function.
e.res.value, e.res.err = f(key)
// Broadcast the ready condition.
close(e.ready)
}
func (e *entry) deliver(response chan<- result) {
// Wait for the ready condition.
<-e.ready
// Send the result to the client.
response <- e.res
}
//!-monitor
I don't understand how close(e.ready)
and <-e.ready
synchronize here. Even after reading the book, I don't understand. Please tell me what the mechanism is.
答案1
得分: 1
e.ready
更常被称为done
通道。这是一种通过关闭done
(e.ready
通道)来告诉您的引用函数某个东西已经准备好的方法。<-e.ready
将会阻塞,直到done
(关闭)。
所以...阅读这段代码的意思是:
1)deliver
等待准备好的信号。
2)call
获取e.res
的数据(e.res.value, e.res.err = f(key)
)。
3)call
通过关闭它来释放done
通道(close(e.ready)
)。
4)deliver
可以通过从<-e.ready
阻塞读取并将数据发送到response
。
英文:
e.ready
is more known as done
channel. this is a way to tell your ref functions that domething is ready by closing done
(e.ready
chan). <-e.ready
is going to block until its done
(closed
).
so... reading this code it means next.
deliver
waits for rediness signal.call
gets data for e.res(
e.res.value, e.res.err = f(key)`)call
releas done channel by closing it (close(e.ready)
)deliver
can move throu block reading from<-e.ready
and send data toresponse
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论