Python3- coroutine & asynchronous IO

1. Concept:

Synchronous IO:

       CPU speed is much faster than disk, network IO, IO operations during the event, such as read and write files, send network data, you need to wait for IO operation to complete before continuing to the next step. This condition is called synchronous IO.

 IO operation when the current thread is suspended, other code executed by the CPU need not execute.

 To achieve concurrency must be multi-threaded / multi-process or asynchronous IO,

Multi-thread / process shortcomings are as follows:

  1. No system can not increase the upper limit of the thread (in other words, the disadvantage is limited by system resources),
  2. System switching overhead increases with the number of threads increases, increasing the switching takes time, cpu reduce the execution time, task completion efficiency drops

 Asynchronous IO:

"When an IO operation code requires a time-consuming, it is only issued IO instruction, IO does not wait for the result, and then went to execute other code. After a while, when the IO return result, and then notify the CPU for processing."

2. Implement

Asynchronous IO model requires a message loop, in a message loop, the main thread continuously repeating "read message - the message handling" process:

1 loop = get_event_loop() 
2 while True:
3     event = loop.get_event()
4     process_event(event)

 

  • When faced with IO operation, code only responsible for issuing IO request, without waiting for the results of IO, and then ends the current round of message processing, message processing to the next round. After the completion of IO operation, will receive a "IO completed" message, can obtain the operation result directly IO processing this message.
  • In the "IO request issued" this time to receive the "IO completion", the

Synchronous IO model , the main thread can only be suspended, but asynchronous IO model, the main thread does not break, but continues to process other messages in the message loop. This

Asynchronous IO model , a thread can simultaneously handle a plurality of IO requests, and the operation does not switch threads. For most IO intensive applications, the use of asynchronous IO will greatly enhance the multi-tasking capabilities of the system.

3. coroutine / micro-threaded / shred Coroutine

  Subroutine

  Also known as sub-function, level call stack implementation, a thread executes a subroutine. The first call, a return, a clear call to order.

  Coroutine

  Similar routines, differences are as follows:

  1. Coroutine execution process may be interrupted within the subroutine, then process goes to other routines at the appropriate time and back again is then performed
  2. Executed by a thread, not the thread switch
  3. Do not need multi-threaded locking mechanism (because only one thread, there is no conflict while writing variable, control of the shared resource is not locked in coroutine, just like a judge status, so the efficiency is much higher than the multi-threading)
 1 #Eg:
 2 def A():
 3     print('1') 
 4     print('2')
 5     print('3')
 6 def B():
 7     print('x') 
 8     print('y') 
 9     print('z')
10 
11 #Coroutine execution may result: in the course of execution of A can be interrupted at any time, to perform B, B may interrupt again during execution performs A 
12 is . 1 2. 3 XY Z

 

  Coroutine and multi-core CPU: multi-process + coroutine

 

Realization (Python) generator

EG: Producer Consumer

. 1  '' ' 
2  Generator achieve
 3      noted Generator function is a consumer, to a consumer after the incoming Produce:
 . 4          1. first call c.send (None) Start generator;
 5          2. Then, once produced things, by c.send (n) to switch execution to the consumer;
 . 6          3. yield by the consumer to get messages, process, and the results returned by yield;
 . 7          4. produce consumer to get the result of the process, continue to produce the next message;
 . 8          . 5 . produce decided not to produce a close consumer by c.close (), the end of the whole process.
9  preemptive multitasking execution by a thread, and consumer Produce collaboration tasks, so called "coroutine", rather than the thread
 10  '' ' 
. 11  
12 is  DEF consumer ():
 13 is      R & lt = ' ' 
14      the while True:
 15         n = yield r
16         if not n:
17             return
18         print('[CONSUMER] Consuming %s...' % n)
19         r = '200 OK'
20 def produce(c):
21     c.send(None)
22     n = 0
23     while n < 5:
24         n = n + 1
25         print('[PRODUCER] Producing %s...' % n)
26         r = c.send(n)
27         print('[PRODUCER] Consumer return: %s' % r)
28     c.close()
29 
30 c = consumer()
31 produce(c)

 

4.asyncio

asyncio standard library Python 3.4 version introduced directly built-in support for asynchronous IO's.

asyncio programming model is a message loop.

We get directly from asyncio module EventLoop a reference, then you need to perform coroutine thrown EventLoop executed, on the realization of asynchronous IO.
EG: Hello World

. 1  '' ' ASYNCIO
 2  
. 3  # Hello world implemented with the following code ASYNCIO:
 . 4  
. 5  1. @ asyncio.coroutine to mark a coroutine type generator,
 6  2. EventLoop into this coroutine execution.
7  
8  Specific implementation process:
 9  the Hello () will first print out the world !, the Hello
 10  yield from syntax to call another generator.
11  Since asyncio.sleep () is a coroutine, so the thread does not wait for asyncio.sleep (), but directly interrupts and execute the next news cycle.
12  when asyncio.sleep () returns, the thread can get return value from the yield from (None here), then proceed with the next line.
13 is  ' '' 
14  Import ASYNCIO
 15  Import Threading
 16  @ asyncio.coroutine
 . 17 def hello():
18      print("Hello world!")
19      # 异步调用 asyncio.sleep(1):
20      r = yield from asyncio.sleep(1)
21      print("Hello again!")
22 
23  # 获取 EventLoop:
24  loop = asyncio.get_event_loop()
25  # 执行 coroutine
26  loop.run_until_complete(hello())
27  loop.close()
28 
29   
. 1  '' ' ASYNCIO
 2  # Another example: asyncio asynchronous network connection to obtain sina, sohu 163 and the Home
 . 3  ' '' 
. 4  @ asyncio.coroutine
 . 5  DEF wget (Host):
 . 6      Print ( ' wget% S ... ' % Host)
 . 7      Connect = asyncio.open_connection (Host, 80 )
 . 8      Reader, Writer = the yield  from Connect
 . 9      header = ' the GET / the HTTP / 1.0 \ R & lt \ NHOst:% S \ R & lt \ n-\ R & lt \ n- ' % Host
 10      writer.Write (header.encode ( ' UTF-. 8 '))
11     yield from writer.drain()
12     while True:
13         line = yield from reader.readline()
14         if line == b'\r\n':
15             break
16         print('%s header > %s' % (host, line.decode('utf-8').rstrip()))
17         # Ignore the body, close the socket
18         writer.close()
19 
20 loop = asyncio.get_event_loop()
21 tasks = [wget(host) for host in ['www.sina.com.cn', 'www.sohu.com', 'www.163.com']]
22 loop.run_until_complete(asyncio.wait(tasks))
23 loop.close()

 

Simplify the identification of asynchronous IO: async and await a new syntax for the coroutine
    1. @ asyncio.coroutine replaced with the async;
    2. Replace the yield from await. 

 1 '''
 2 简化版
 3 '''
 4 import asyncio
 5 @asyncio.coroutine
 6 def hello():
 7     print("Hello world!")
 8     r = yield from asyncio.sleep(1)
 9     print("Hello again!")
10 
11 async def hello():
12     print("Hello world!")
13     r = await asyncio.sleep(1)
14     print("Hello again!")
15 # 获取 EventLoop:
16 loop = asyncio.get_event_loop()
17 # 执行 coroutine
18 loop.run_until_complete(hello())
19 loop.close()

 

 1 #练习:
 2 
 3 async def wget(host):
 4     print('wget %s...' % host)
 5     connect = asyncio.open_connection(host, 80)
 6     reader, writer = await connect
 7     header = 'GET / HTTP/1.0\r\nHost: %s\r\n\r\n' % host
 8     writer.write(header.encode('utf-8'))
 9     await writer.drain()
10     while True:
11         line = await reader.readline()
12         if line == b'\r\n':
13             break
14         print('%s header > %s' % (host, line.decode('utf-8').rstrip()))
15         # Ignore the body, close the socket
16         writer.close()
17 
18 loop = asyncio.get_event_loop()
19 tasks = [wget(host) for host in ['www.sina.com.cn', 'www.sohu.com', 'www.163.com']]
20 loop.run_until_complete(asyncio.wait(tasks))
21 loop.close()

 

5.aiohttp

asyncio can achieve single-threaded concurrent IO operations. If only the client, not the power play. If asyncio used on the server side, such as Web servers, since an HTTP connection is IO operations, it is possible to achieve high single-threaded concurrent + coroutine support multiple users.
asyncio implements TCP, UDP, SSL and other protocols, aiohttp framework is based on HTTP asyncio achieved.

. 1  '' ' 
2  ASYNCIO threaded concurrent IO operations can be realized.
3  If only the client, not the power play.
4  If ASYNCIO used on the server side, such as Web servers, since an HTTP connection is IO operations,
 5  can be used to achieve high single-threaded + coroutine supporting multiple users concurrently
 . 6  ASYNCIO implements TCP, UDP, SSL and other protocols, aiohttp is based asyncio implemented HTTP frame
 . 7  Eg of: preparation of the HTTP server, were treated URL
 . 8      / - Home Back B '<h1 of> Index </ h1 of>';
 . 9      / hello / {name} - returns the text hello the URL parameter,% s !.
10  '' ' 
. 11  
12 is  Import ASYNCIO
 13 is  from aiohttp Import Web
 14  
15 the async DEF index (Request): #Parameters, aiohttp.web.request example, contains all the information sent from the browser the HTTP protocol which generally do not own configuration 
16      the await asyncio.sleep (0.5 )
 . 17      return web.Response (= body B ' <h1 of> Index < / h1> ' , headers = { ' Content-of the type ' : ' text / HTML ' })
 18  # here unless specified headers, visit the Web site to download the binary files will pop 
19  # Header with the Content-Type text / plain, supports data is encoded in plain text. The browser will automatically call html parser in obtaining this file to the file accordingly. 
20 is  # aiohttp.web.response example, by the web.Response (body = '') configuration, inherited from StreamResponse, to construct a HTTP response function 
21  #类声明 class aiohttp.web.Response(*, status=200, headers=None, content_type=None, body=None, text=None)
22 async def hello(request):
23     await asyncio.sleep(0.5)
24     text = '<h1>hello, %s!</h1>' % request.match_info['name']
25     return web.Response(body=text.encode('utf-8'),headers={'content-type':'text/html'})
26 
27 async def init(loop):#loop is passed into the function coroutine 
28      # App = web.Application (loop = loop), according to the parameters given remove 
29      App web.Application = () # create a Web server app, processing url, http information 
30      app.router.add_route ( ' the GET ' , ' / ' , index) # the handler registered into Router 
31 is      app.router.add_route ( ' the GET ' , ' / Hello / {name} ' , Hello) # processing function corresponding to URL (HTTP method metho, URL path path) binding, return the browser URL content handler tap 
32  
33 is  # lower section of a modified version of the code, error prompt app.make_handler () are discarded using web.AppRunner (app) Alternatively, using follows 
34     = Runner web.AppRunner (App)
 35      the await runner.setup ()
 36      Site = web.TCPSite (Runner, ' localhost ' , 8000 )
 37 [      the await site.start ()
 38 is      Print ( ' Server HTTP AT Started: //127.0. 0.1: 8000 ... ' )
 39  
40      # at the beginning: 
41      # to use co-creation process monitoring services, to create a good return, bind IP, port, HTTP protocol suite listening service coroutine 
42      # SRV = the await Loop. create_server (app.make_handler (), '127.0.0.1', 8000) 
43 is      # return SRV 
44 is  
45 Loop asyncio.get_event_loop = () #Create a coroutine 
46 loop.run_until_complete (the init (Loop)) # initialize the coroutine, running coroutine know complete 
47 loop.run_forever () # running coroutine until the call stop

 

Guess you like

Origin www.cnblogs.com/jpga/p/12566663.html