python - Is this multi-threaded function asynchronous -
i'm afraid i'm still bit confused (despite checking other threads) whether:
- all asynchronous code multi-threaded
- all multi-threaded functions asynchronous
my initial guess no both , proper asynchronous code should able run in 1 thread - can improved adding threads example so:
so constructed toy example:
from threading import * queue import queue import time def do_something_with_io_lag(in_work): out = in_work # imagine work involves sending # on internet , processing output # once arrives time.sleep(0.5) # simulate io lag print("hello, bee number: ", str(current_thread().name).replace("thread-","")) class workerbee(thread): def __init__(self, q): thread.__init__(self) self.q = q def run(self): while true: # work queue work_todo = self.q.get() # function simiulate i/o lag do_something_with_io_lag(work_todo) # remove task queue self.q.task_done() if __name__ == '__main__': def time_me(nmbr): number_of_worker_bees = nmbr worktodo = ['some input work'] * 50 # create queue q = queue() # fill work [q.put(onework) onework in worktodo] # launch processes _ in range(number_of_worker_bees): t = workerbee(q) t.start() # block until queue empty q.join() # run code in serial mode (just 1 worker) %time time_me(nmbr=1) # wall time: 25 s # 50 requests * 0.5 seconds io lag # me gets processed bee number: 59 # run code using multi-tasking (launch 50 workers) %time time_me(nmbr=50) # wall time: 507 ms # 0.5 second io lag + 0.07 seconds took launch them # gets processed different bees
is asynchronous?
to me code not seem asynchronous because figure 3 in example diagram. i/o call blocks thread (although don't feel because blocked in parallel).
however, if case confused why requests-futures considered asynchronous since wrapper around threadpoolexecutor:
with concurrent.futures.threadpoolexecutor(max_workers=20) executor: future_to_url = {executor.submit(load_url, url, 10): url url in get_urls()} future in concurrent.futures.as_completed(future_to_url): url = future_to_url[future] try: data = future.result()
can function on 1 thread?
especially when compared asyncio, means can run single-threaded
there 2 ways have program on single processor “more 1 thing @ time.” multi-threaded programming simplest , popular way it, there different technique, lets have advantages of multi-threading, without using multiple threads. it’s practical if program largely i/o bound. if program processor bound, pre-emptive scheduled threads need. network servers processor bound, however.
firt of all, 1 note concurrent.futures.future
not same asyncio.future
. basicly it's abstraction - object, allows refer job result (or exception, result) in program after assigned job, before completed. it's similar assigning common function's result variable.
multithreading: regarding example, when using multiple threads can code "asynchronous" several operations performed in diffeent threads @ same time without waiting each other complete, , can see in timing results. , you're right, function due sleep
blocking, blocks worker thread specified time, when use several threads threads blocked in parallel. if have 1 job sleep
, other 1 without , run multiple threads, 1 without sleep
perform calculations while other sleep. when use single thread, jobs performed in in serial manner 1 after other, when 1 job sleeps other jobs wait it, thay don't exist untill it's there turn. pretty proven time tests. thing happened print
has "thread safety", i.e. print uses standard output, single shared resource. when multiple threads tried print @ same time switching happened inside , got strange output. (this show "asynchronisity" of multithreaded example.) preven such errors there locking mechanisms, e.g. locks, semaphores, etc.
asyncio: better understand purpose note "io" part, it's not 'async computation', 'async input/output'. when talking asyncio don't think threads @ first. asyncio event loop , generators (coroutines). event loop arbiter, governs execution of coroutines (and callbacks), registered loop. coroutines implemeted generators, i.e. functions allow perform actions iteratively, saving state @ each iteration , 'returning', , on next call continuing saved state. basicly event loop while true:
loop, calls assigned coroutines/generators 1 after another, , provide result or no-result on each such call - provides possibility "asynchronicity". (a simplification, there's scheduling mechanisms, optimize behavior.) event loop in situation can run in single thread , if coroutines non-blocking give true "asynchronicity", if blocking it's basicly linear execution.
you can achieve same thing explicit multithreading, threads costly - require memory assigned, switching them takes time, etc. on other hand asyncio api allows abstract actual implementation , consider jobs performed asyncronously. it's implementation may different, includes calling os api , os decides do, e.g. dma, additional threads, specific microcontroller use, etc. thing works io due lower level mechanisms, hardware stuff. on other hand, performing computation require explicit breaking of computation algorithm peices use asyncio coroutine, separate thread might better desicion, can launch whole computation 1 there. (i'm not talking algorithms special parallel computing). asyncio event loop might explicitly set use separate threads coroutines, asyncio multithreading.
regarding example, if you'll implement function sleep
asyncio coroutine, shedule , run 50 of them single threaded, you'll time similar first time test, i.e. around 25s
, blocking. if change yield [asyncio.sleep][3](0.5)
(which coroutine itself), shedule , run 50 of them single threaded, called asynchronously. while 1 coroutine sleep other started, , on. jobs complete in time similar second multithreaded test, i.e. close 0.5s
. if add print
here you'll output used single thread in serial manner, output might in different order order of coroutine assignment loop, coroutines run in different order. if use multiple threads, result close last 1 anyway.
simplification: difference in multythreading , asyncio in blocking/non-blocking, basicly blocking multithreading come close non-blocking asyncio, there're lot of differences.
- multithreading computations (i.e. cpu bound code)
- asyncio input/output (i.e. i/o bound code)
regarding original statement:
- all asynchronous code multi-threaded
- all multi-threaded functions asynchronous
i hope able show, that:
- asynchronous code might both single threaded , multi-threaded
- all multi-threaded functions called "asynchronous"
Comments
Post a Comment