Странная проблема в << Go языке программирования >> - PullRequest
1 голос
/ 11 апреля 2020

Описание:
Вот код в главе 9-7 из Go Язык программирования .

Вы должны вызвать fun c New () , чтобы инициировать контейнер перед вызовом любых других функций.

Странно, что автор создал блокирующий канал в fun c New () для отправки запросов.

Я думаю, это заставит программу работать serial .

Например: если существует более одной программы, вызывающей fun c Get () одновременно, будут ли запросы обрабатываться последовательно в l oop сервер рутин?

Может ли кто-нибудь дать мне объяснение? Спасибо!

/**
 * create a memo and run the monitor goroutine of it.
 * here is a question:
 * since the request channel is blocking, does it mean that func Get is serial?
 */
func New(f Func) *Memo {
    memo := &Memo{requests: make(chan request)}
    go memo.server(f)
    return memo
}

/**
 * make a new request to query the data.
 */
func (memo *Memo) Get(key string) (interface{}, error) {
    response := make(chan result)
    memo.requests <- request{key, response}
    res := <-response
    return res.value, res.err
}

/**
 * start the monitor goroutine.
 * Notice that the cache is running here.
 */
func (memo *Memo) server(f Func) {
    cache := make(map[string]*entry)

    // handle each of the requests
    for req := range memo.requests {
        e := cache[req.key]
        if e == nil {
            e = &entry{ready: make(chan struct{})}
            cache[req.key] = e
            go e.call(f, req.key)
        }
        go e.deliver(req.response)
    }
}

1 Ответ

2 голосов
/ 11 апреля 2020

Функция New запускает server в программе, а server читает запросы из канала requests. Поскольку requests небуферизован, в него может писать только одна программа. Однако обратите внимание на реализацию сервера: он читает запрос и запускает новую процедуру для обработки этого запроса, немедленно возвращаясь к прослушиванию с него. Таким образом, gorotines обработки запроса создаются один за другим, но каждая goroutine запускается одновременно.

Когда вы вызываете Get, он ждет, пока метод server обработает запрос, но как только обработчик запроса goroutine создан, он может обслуживать другие Get запросы. Каждый вызов Get будет ожидать поступления ответа на другой канал, написанный другой программой.

Короче говоря: нет, Get можно вызывать из многих программ, и каждый вызов создаст отдельная процедура для обработки этого запроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...