четверг, 31 января 2019 г.

Эффективный Go: текущий буфер

Инструменты параллельного программирования могут облегчить выражение даже не-многопоточных идей. Вот пример, извлеченный из RPC пакета. Клиентская программа выполняет цикл получения данных из какого-либо источника, возможно сети. Чтобы избежать выделения и освобождения буферов, она сохраняет свободный список, и использует буферизованный канал для его представления. Если канал пуст, выделяется новый буфер. Когда буфер сообщений готов, он отправляется на сервер serverChan.

var freeList = make(chan *Buffer, 100)
var serverChan = make(chan *Buffer)

func client() {
    for {
        var b *Buffer
        // Берем буфер, если он доступен; 
        // иначе - аллоцируем новый.
        select {
        case b = <-freeList:
            // Получили буфер; больше ничего не делаем.
        default:
            // Нет свободных, поэтому аллоцируем новый.
            b = new(Buffer)
        }

        // Читаем следующее сообщение из сети.
        load(b)              
        serverChan <- b  // Отправляем на сервер.
    }
}

Цикл сервера получает каждое сообщение от клиента, обрабатывает его, и возвращает буфер в свободный список.

func server() {
    for {
        b := <-serverChan    // Ожидание работы.
        process(b)
        // Повторно используем буфер, если есть место.
        select {
        case freeList <- b:
            // Буфер в свободном списке; 
            // больше ничего не делаем.
        default:
            // Список свободных полон, просто продолжаем.
        }
    }
}

Клиент пытается получить буфер из freeList; если ни один не доступен, он выделяет новый. Отправка сервером в freeList возвращает b в список свободных если список не полный, иначе буфер выбрасывается, чтобы быть утилизированным сборщиком мусора. (Условие default в select операторах выполняются, когда ни один другой случай не готов, это означает, что select никогда не блокируется.) Эта реализация создает список без утечек памяти всего в несколько строк, полагаясь на буферизованный канал и сборщик мусора для учета.


Читайте также:


Комментариев нет:

Отправить комментарий