asyncio
threading
multiprocessing
C / Cython
I/O-bound
CPU-bound
HÃ¥ndter flere oppgaver samtidig
Gjør flere oppgaver i parallell
Gjør async programmering enklere
trio
unsync
Mye boiler plate
import asyncio
async def just_get_this_done():
await do_io_stuff()
async def and_this():
await do_io_stuff()
def annoying_boiler_plate():
loop = asyncio.get_event_loop()
future = asyncio.gather(just_get_this_done(), and_this())
loop.run_until_complete(future)
if __name__ == '__main__':
annoying_boiler_plate()
from concurrent.futures import ProcessPoolExecutor
def just_get_this_done():
do_cpu_stuff()
def and_this():
do_cpu_stuff()
def annoying_boiler_plate():
with ProcessPoolExecutor() as ppe:
ppe.submit(just_get_this_done),
ppe.submit(and_this)
if __name__ == '__main__':
annoying_boiler_plate()
from concurrent.futures import ThreadPoolExecutor
def just_get_this_done():
do_io_stuff()
def and_this():
do_io_stuff()
def annoying_boiler_plate():
with ThreadPoolExecutor() as tpe:
tpe.submit(just_get_this_done)
tpe.submit(and_this)
if __name__ == '__main__':
annoying_boiler_plate()
asyncio
threading
multiprocessing
Ulike interfaces
result = ProcessPoolExecutor()
.submit(my-func, args)
.result()
result = await my_func(args)
vs.
Krunglete å kombinere
asyncio, threading og multiprocessing
from concurrent.futures import ProcessPoolExecutor
import asyncio
async def extract():
return 21
def transform(input):
return input * 2
if __name__ == '__main__':
loop = asyncio.get_event_loop()
extracted_result = loop.run_until_complete(extract())
with ProcessPoolExecutor() as executor:
transformed = executor.submit(transform, extracted_result)
print(transformed.result())
En decorator som kan brukes på async- og vanlige funksjoner
from unsync import unsync
@unsync()
def just_get_this_done():
do_stuff()
@unsync()
def and_this():
do_stuff()
@unsync()
async def and_this_too():
await do_stuff()
if __name__ == '__main__':
just_get_this_done()
and_this()
and_this_too()
Med cpu_bound=True kjøres funksjonen i en separat prosess
from unsync import unsync
@unsync()
def just_get_this_done():
do_stuff()
@unsync(cpu_bound=True)
def and_this():
do_stuff()
@unsync()
async def and_this_too():
await do_stuff()
if __name__ == '__main__':
just_get_this_done()
and_this()
and_this_too()
Felles interface for henting av resultat
@unsync()
def just_get_this_done():
return do_stuff()
@unsync(cpu_bound=True)
def and_this():
return do_stuff()
@unsync()
async def and_this_too():
return await do_stuff()
if __name__ == '__main__':
tasks = [
just_get_this_done()
and_this()
and_this_too()
]
results = [task.result() for task in tasks]
Støtter chaining
from unsync import unsync, Unfuture
@unsync()
async def extract():
return 21
@unsync(cpu_bound=True)
def transform(input: Unfuture):
return input.result() * 2
@unsync()
def load(input: Unfuture):
with open('the_answer.txt', 'w') as file:
file.write(input.result())
extract().then(transform).then(load).result()
# TypeError: cannot pickle '_asyncio.Task' object
(men ikke med cpu_bound=True)
from unsync import unsync, Unfuture
@unsync()
async def extract():
return 21
@unsync()
def transform(input: Unfuture):
return input.result() * 2
@unsync()
def load(input: Unfuture):
with open('the_answer.txt', 'w') as file:
file.write(input.result())
extract().then(transform).then(load).result()
Unfuture som wrapper for asyncio.Task og concurrent.futures.Future
>>> @unsync()
... async def coro():
... pass
...
>>> future = coro()
>>>
>>> type(future)
<class 'unsync.unsync.Unfuture'>
>>> type(future.future)
<class '_asyncio.Task'>
>>> type(future.concurrent_future)
<class 'concurrent.futures._base.Future'>
>>> future.__await__
<bound method Unfuture.__iter__ of <unsync.unsync.Unfuture object at 0x7f72e250bf70>>
async uten unsync
async med unsync
unsync med chaining
sync
kurs:
unsync:
demo-kode:
dunsync: