14. asyncio

14. asyncio

14. asyncio

21 май 2014

Конкурентност vs. паралелизъм?

anyone?

Похвати за конкурентност?

зелена нишка ∈ системна нишка ∈ процес

Преди това...

Още малко за multiprocessing

Паралелизиран map

import urllib
from multiprocessing import Pool

urls = [
    'http://www.python.org',
    'http://www.python.org/about/',
    'http://github.com/',
    'http://kefche.com/',
]

def fetch(url):
    try:
        return urllib.request.urlopen(url).status
    except urllib.error.URLError as e:
        return e.code

pool = Pool(4)
statuses = pool.map(fetch, urls)
pool.close()
pool.join()

Gotchas

fetch() трябва да е дефинирана преди конструирането на pool (спомнете си какво точно прави fork())

yield from

Дърво 1.0

Да обхождаме дървета

class Node:
    def __init__(self, value):
        self.left = []
        self.value = value
        self.right = []

    def iterate(self):
        for node in self.left:
            yield node.value
        yield self.value
        for node in self.right:
            yield node.value

Къде сбъркахме?

Дърво 2.0

..
def iterate(self):
    for node in self.left:
        yield from node.iterate()
    yield self.value
    for node in self.right:
        yield from node.iterate()

concurrent.futures

Удобен модул за асинхронно изпълнение на неща

+-- Future
+-- Executor
  +-- ThreadPoolExecutor
  +-- ProcessPoolExecutor

concurrent.futures.Future

Обект, който енкапсулира нещо за изпълнение в конкурентна среда.Държи състоянието му и ни дава удобен интерфейс за работа с него

concurrent.futures.Executor

Не използваме `Future`-ите директно, а ги създаваме през съответния `Executor`

Paralellizing CPU-bound tasks

Помните ли как ви казахме, че Python не може да решава такива проблеми?

PRIMES = [
    112272535095293,
    112582705942171,
    112272535095293,
    115280095190773,
    115797848077099,
    1099726899285419]

def is_prime(n):
  # ...

def main():
    with concurrent.futures.ProcessPoolExecutor() as executor:
        for number, prime in zip(PRIMES, executor.map(is_prime, PRIMES)):
            print('{} is prime: {}'.format(number, prime))

пълния пример

Paralellizing CPU-bound tasks

Помните ли как ви казахме, че Python не може да решава такива проблеми?

Корутини

Малки независими изпълними единици, които кооперативно си предават контрол над управлението.

Корутини

greenlets

asyncio

В python 3.4 се появява модула asyncio

Важно е да си в event loop-а. Той отговаря за предаването на контрола между корутините

Event loop

Искаме да реагираме на събитие по определен начин

Event loop-а проверява на определен(относително кратък) период от време дали се е случило събитиеи ни уевдомява, за да можем да реагираме

Event loop

Когато използваме asyncio всяка нишка има по един event loop, отговарящ за задачите в нея

Event loop

GO! GO! GO!

Пример

който ще наречем "прост"

gist

Въпроси?