Эквивалент цикла событий Python asyncio в Go lang - PullRequest
0 голосов
/ 11 ноября 2018

Я использую асинхронный / параллельный asyncio цикл обработки событий в Python3.x .

Есть ли в Go lang эквивалент asyncio или сопрограмм с производительностью параллелизма, использующей нить ?


[ Примечание ]:

Не параллелизм + параллелизм (многопроцессорная обработка).


[UPDATE]:

Вот асинхронный цикл обработки событий, использующий asyncio в Python для лучшего понимания:

import asyncio
import time

async def async_say(delay, msg):
    await asyncio.sleep(delay)
    print(msg)

async def main():
    task1 = asyncio.ensure_future(async_say(4, 'hello'))
    task2 = asyncio.ensure_future(async_say(6, 'world'))

    print(f"started at {time.strftime('%X')}")
    await task1
    await task2
    print(f"finished at {time.strftime('%X')}")

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

Из:

started at 13:19:44
hello
world
finished at 13:19:50

Любая помощь будет принята с благодарностью.

Ответы [ 2 ]

0 голосов
/ 11 ноября 2018

В терминах Python цикл обработки событий встроен в Go. Вы запускаете две процедуры с go async_say(...) и ждете их завершения, например, используя канал или группу ожидания .

Простой перевод вашего кода на Go может выглядеть так:

package main

import "fmt"
import "time"

func async_say(delay time.Duration, msg string, done chan bool) {
    time.Sleep(delay)
    fmt.Println(msg)
    done <- true
}

func main() {
    done1 := make(chan bool, 1)
    go async_say(4 * time.Second, "hello", done1)
    done2 := make(chan bool, 1)
    go async_say(6 * time.Second, "world", done2)
    <-done1
    <-done2
}

Обратите внимание, что, в отличие от Python (и JavaScript, и т. Д.), Функции Go не бывают разных цветов в зависимости от того, являются они асинхронными или нет. Они могут all выполняться асинхронно, а эквивалент asyncio встроен в стандартную библиотеку.

0 голосов
/ 11 ноября 2018

Вам не нужно это в Go, так как в Go это будет анти-паттерном.

Вместо этого в Go у вас есть управление дескрипторами "pollable" - такими как сокеты - тесно интегрированными со средой выполнения и планировщиком работы с программой. Это позволяет вам писать обычный последовательный код, который будет внутренне обрабатываться через зависящий от платформы интерфейс «с событиями» (такой как epoll в Linux, kqueue в FreeBSD и IOCP в Windows). Как только программа пытается выполнить какой-либо ввод-вывод для сокета, а сокет не готов, процедура приостанавливается до тех пор, пока эти данные не будут готовы, после чего они будут возобновлены прямо в том месте, где они были приостановлены.

Следовательно, в Go вы просто создаете отдельную программу, которая обслуживает каждый запрос, который должен быть выполнен или обслуживается одновременно с другими, и пишете простой последовательный код для его обработки.

Для обратного хода начните здесь и здесь .

Учебники, объясняющие, как работает планировщик Go, например, это и это .

...