pygrunn2014

2020-02-27 160浏览

  • 1.gevent,  threads  &  async  frameworks   Denis  Bilenko
  • 2.What  is  gevent?   • green  threads  for  Python   – Coopera>ve,  only  switch  at  I/O   • greenlet  for  context  switching   – No  syscalls   • libev  for  event  loop   – PreEy  fast
  • 3.status   • currentstable:1.0.1   – Runs  on  Python  2.5  –  2.7   • masterbranch:1.1   – Support  forPyPy:85%  tests  pass   – Support  forPython3:53%  tests  pass   • Basics  and  sockets  work   • Subprocesses  and  fileobjects  todo
  • 4.import  thread,  socket       def  send(host):          sock  =  socket.create_connec>on((host,  80))          sock.sendall("GET  /  HTTP/1.0\r\n\r\n”)     #  do  two  requests  in  parallel   create_new_thread(send,  ('python.org',  ))   create_new_thread(send,  ('gevent.org',  ))
  • 5.#import  thread,  socket   from  gevent  import  thread,  socket     def  send(host):          sock  =  socket.create_connec>on((host,  80))          sock.sendall("GET  /  HTTP/1.0\r\n\r\n”)     #  do  two  requests  in  parallel   create_new_thread(send,  ('python.org',  ))   create_new_thread(send,  ('gevent.org',  ))
  • 6.drop-­‐in  modules   from  gevent  import    socket,    ssl,    subprocess,    thread,    local,    queue
  • 7.stdlib  compa>bility     • • • • less  to  learn   API  is  more  stable  across  gevent  versions   we  can  use  stdlib's  tests  to  verify  seman>cs   trivial  to  port  libraries  and  apps  to  gevent
  • 8.from  gevent  import  monkey;  monkey.patch_all()       import  requests   from  flask  import  Flask   app  =  Flask(__name__)       @app.route('/')   def  hello_world():          return  requests.get('hEp://python.org').content     app.run()
  • 9.A  TCP  server     def  echo(socket,  address):          for  line  in  socket.makefile():                  socket.sendall(line)     gevent.server.StreamServer(':5000’,  handle).start()
  • 10.gevent.wait([…  objects  …])     • wait  for  any  gevent  object   • extendable  through  rawlink(callback)
  • 11.gevent.wait([…  objects  …],  >meout=5)     • limit  wai>ng  to  certain  >me
  • 12.gevent.wait([…  objects  …],  count=N)     • only  wait  for  N  objects   • return  value  is  a  list  of  ready  objects
  • 13.gevent.wait()     • wait  for  everything   • “background”  watchers  ref=False   • gracefulshutdown:– stop  accep>ng  new  requests   – gevent.wait()
  • 14.geventserver     • • • • •     pre-­‐fork,  <999LOC   supports  any  gevent  server,  not  just  HTTP   graceful  shutdown   can  beembedded:import  geventserver   reports  long  loop  itera>ons     github.com/surfly/geventserver
  • 15.Why?     • Avoid  complexi>es  of  event  loops   • Avoid  costs  of  real  threads
  • 16.Complexi>es  of  event  loops   A  simple     sock  =  socket.create_connec>on((host,  80))   sock.sendall("GET  /  HTTP/1.0\r\n\r\n”)   data  =  sock.recv(1024)     becomes
  • 17.Complexi>es  of  event  loops     def  connec>onMade(self):          …   def  dataReceived(self,  data):          …   def  connec>onError(self,  error):          …
  • 18.async  vs.  sync   excep>ons  for  I/O  errorstry:connect()   exceptIOError:…   def  connec>onMade(self):          …     def  connec>onError(self,  error):          …
  • 19.async  vs.  sync   context  managers   with  open(‘log’,  ‘w’)  aslog:io_opera>on()          log(“connected”)          io_opera>on()          log(“sent”)     #  log  object  is  closed  by  “with”             explicit  state  machine
  • 20.async  vs.  sync   synchronous  programming  model   handle_result(func(params))   d  =  Deferred()   func(d)   d.add_callback(handle_result)   d.add_errback(handle_error)
  • 21.Giving  up   • excep>on  handling   • context  managers   • synchronous  programming  style   • 3rdparty  libraries       A  subset  of  Python  without  baEeries.
  • 22.Generators  /  PEP-­‐3156?   • Help  somewhat   • But  notenough:with  conn.cursor()  ascurs:curs.execute(SQL)    #  cursor()  needs  to  do  I/O  in  __exit__     • No  compa>bility  with  threading  /  3rdparty   libraries
  • 23.Corou>nes   •generators:non-­‐stackful  corou>ne   – Only  yield  to  parent   – Need  special  syntax   – Only  saves  the  top  frame   •greenlet:stackful  corou>ne   – Switching  is  just  a  func>on  call   – Switching  to  any  target   – Saves  the  whole  stack,  like  a  thread
  • 24.Why?     • Avoid  complexi>es  of  event  loops   • Avoid  costs  of  real  threads
  • 25.Threads  vs  green  threads   • crea>on   – thread.start_new_thread:28usec   –gevent.spawn:5usec   – gevent.spawn_raw:1usec     • does  not  maEer  if  used  via  pool
  • 26.Threads  vs  green  threads   memory   •threads:8MB  of  stack  by  default   •greenlet:only  allocate  what’s  actually  used   – 350  bytes  per  Python  frame   – 10-­‐15KB     • does  not  maEer  since  the  memory  is  virtual   – limits  number  of  threads  on  32bit  arch
  • 27.Gevent  server   def  handle(socket,  addr):          #  read  out  the  request          for  line  in  socket.makefile():                  if  not  line.strip():                          break          #  send  the  response          socket.sendall(HTTP_RESPONSE)          socket.close()     from  gevent.server  import  StreamServer   StreamServer(':5000',  handle).serve_forever()
  • 28.Threaded  server   queue  =  Queue()     def  worker():          whileTrue:'>True: