2015-08-07 5 views
0

Я пытался понять код в https://golang.org/doc/codewalk/sharemem/ Хотя я получаю большую часть информации о передаче ресурсов по каналу, я не могу понять бесконечный цикл, в котором работает программа Как программа выполняет функцию Poller бесконечно, когда канал «in» в функции poller (который получает от основной функции) запускает только 3 процедуры poller go?Понимание кода: Совместное использование ресурсов путем общения

Я получаю идею StateMonitor с анонимной функцией go с бесконечным циклом. Но он не может обновлять LogState без получения от функции Poller. Я предполагаю, что программа выполняет запрос Get к URL-адресам бесконечно.

Чтобы подтвердить, что я не ошибаюсь в отношении того, что я понял, я протестировал программу, включив и выключил Wi-Fi, чтобы узнать, меняется ли журнал. К моему удивлению, он делает это за несколько итераций, но после этого перестает отвечать на мои изменения и продолжает показывать тот же журнал. Итак, значит ли это, что программа глючит? Или я не понял некоторые фундаментальные понятия?

ответ

0

Как программа выполняет функцию Poller бесконечно, когда канал «in» в функции poller (который получает от основной функции) запускает только 3 процедуры проверки poller?

Таким образом, первая программа создает два пуллеров:

for i := 0; i < numPollers; i++ { 
    go Poller(pending, complete, status) 
} 

затем посылает три ресурса в ожидание:

for _, url := range urls { 
    pending <- &Resource{url: url} 
} 

Каждого Poller считываемых из очереди и опросов ресурса:

for r := range in { 
    s := r.Poll() 
    status <- State{r.url, s} 
    out <- r 
} 

Этот код исполняет бесконечно, но он блокирует чтение из очереди, как правило. Таким образом, эти циклы ждут появления следующего значения. практически шаг

Давайте над ним:

  1. Существует два пуллеров чтения ресурсов.
  2. Программа отправляет первый ресурс в очередь.
  3. Один из опылителей получает ресурс и начинает пул. Другой ждет.
  4. В какой-то момент программа отправляет новый ресурс в очередь.
  5. Как первый опроллер занят, второй разблокируется и начинает опрос.
  6. Программа отправляет третий ресурс и блокирует, поскольку два участника были заняты.
  7. Когда один из опылителей завершает работу, он берет последний ресурс и продолжает.
  8. В то же время основная программа считывает значения из полной очереди.

for r := range in { s := r.Poll() status <- State{r.url, s} out <- r } Как этот код работать бесконечно? Если он перебирает канал «in», а «in» получает свои ресурсы из ожидающей очереди, он должен заканчиваться после нескольких итераций. Я думаю, что это именно та часть, которую я не понимаю.

Чтобы уточнить, in не получает ресурсы от pending очереди. inpending очереди. Очередь (или канал, которую я использую взаимозаменяемо) можно закрыть, вызвав close, но пока она не будет закрыта явно, она считается живой. Любое чтение из него блокирует текущий goroutine, пока не будет указано следующее значение. Затем возобновляется роротин.

Предполагаю, что вы продолжаете думать о каналах, как о массиве с фиксированным количеством элементов. Они не. Подумайте, что они любят массив с бесконечным количеством элементов, но с блокировкой чтения, которое может генерировать исключение (что приблизительное приближение закрытия очереди, если вы не знакомы с понятием).

+0

'для г: = в диапазоне { S: = r.Poll() статус <- Государство {r.url, s} из <- г }' Как делает этот код бегать бесконечно? Если он перебирает канал «in», а «in» получает свои ресурсы из ожидающей очереди, он должен заканчиваться после нескольких итераций. Я думаю, что это именно та часть, которую я не понимаю. Особенно это происходит в этом разделе. Спасибо за ваше пошаговое объяснение. – Sunil

+0

обновил мой ответ –

0

Операция отправки по каналу блокируется до тех пор, пока приемник не будет доступен для одного и того же канала: если для канала нет адресата, в канал не может быть добавлено другое значение. И наоборот: никакое новое значение не может быть отправлено в канал, когда канал не пуст! Таким образом, операция отправки будет ждать, пока канал снова станет доступен.

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

Чтобы разблокировать канал, нам нужно вытащить данные из канала в бесконечном цикле.

Это объяснение, почему программа отправляет и считывает данные в бесконечном цикле.

+0

Исправьте меня, если я ошибаюсь. В программе есть только один бесконечный цикл, который находится внутри функции SateMonitor. Это было бы совершенно разумно для меня, если бы я мог понять, как функция StateMonitor взаимодействует с функцией Poller. – Sunil

Смежные вопросы