Python Day38 coprocessor, io model

Source: Internet
Author: User

First, Introduction:

1, co-process: is a single-threaded concurrency, also known as micro-threading, fiber. English name Coroutine. One sentence describes what a thread is: The process is a lightweight thread of user-state, that is, the process is scheduled by the user program itself.

Emphasize:

1. Python threads are at the kernel level, that is, scheduled by the operating system control (such as single-threaded encounters io or long execution time will be forced to hand over the CPU Execute permissions, switch other threads to run)
2.
single-wire range open the process, once encountered Io, will be from the application level (not the operating system) control switch, so as to improve efficiency (!!!) Non-IO operation switching is not efficiency-independent)

2, compared with the operating system control thread switching, the user in a single-threaded control of the transition of the process
Pros:
1. The transition cost of the association is smaller, it belongs to the program-level switch, the operating system is not fully aware, and therefore more lightweight
      2. Concurrency can be achieved within a single thread to maximize CPU utilization
Disadvantages:
1. The nature of the process is single-threaded, unable to take advantage of multi-core, can be a program to open multiple processes, each in-process open multiple threads, each line range open the Co -
2. The association refers to a single thread, so once the association is blocked, it will block the entire thread

Summary of the characteristics of the process:

    1. Concurrency must be implemented in only one single thread
    2. No lock required to modify shared data
    3. The context stack in the user program that holds multiple control flows
    4. Additional: A co-process encountered IO operation automatically switch to other Io,yield (how to implement detection, Greenlet can not be implemented, the use of the Gevent module (select mechanism))
Second, Greenlet

If we had 20 tasks within a single thread, it would be cumbersome to use the yield generator in order to switch between multiple tasks (we need to get the generator initialized once before calling send ...). Very cumbersome), while using the Greenlet module can be very simple to achieve these 20 tasks directly switching

 fromGreenletImportGreenletdefEat (name):Print('%s Eat 1'%name) G2.switch ('Egon')    Print('%s Eat 2'%name) G2.switch ()defPlay (name):Print('%s Play 1'%name) G1.switch ()Print('%s Play 2'%name) G1=Greenlet (Eat) G2=Greenlet (play) G1.switch ('Egon')#parameters can be passed in at the first switch, and will not be required at any later time

Simple switching (in the absence of an IO or a duplication of memory space) will slow down the execution of the program

#Sequential ExecutionImport TimedefF1 (): Res=1 forIinchRange (100000000): Res+=IdefF2 (): Res=1 forIinchRange (100000000): Res*=Istart=Time.time () F1 () F2 () Stop=time.time ()Print('run time is%s'% (Stop-start))#10.985628366470337#Toggle fromGreenletImportGreenletImport TimedefF1 (): Res=1 forIinchRange (100000000): Res+=i g2.switch ()defF2 (): Res=1 forIinchRange (100000000): Res*=I G1.switch () Start=time.time () G1=Greenlet (F1) G2=Greenlet (F2) G1.switch () Stop=time.time ()Print('run time is%s'% (Stop-start))#52.763017892837524

Reenlet just provides a more convenient way to switch than generator, when cutting to a task execution if you encounter Io, then blocking in place, still does not solve the problem of automatically switching to the IO to improve efficiency.

The code for these 20 tasks for single-line thread usually has both a computational and a blocking operation, and we can get stuck in the execution of Task 1 o'clock and use the blocking time to perform the task so that we can improve efficiency, which uses the Gevent module.

Iii. introduction of Gevent

Gevent is a third-party library that makes it easy to implement concurrent or asynchronous programming through Gevent, and the main pattern used in Gevent is Greenlet, which is a lightweight coprocessor that accesses Python in the form of a C extension module. Greenlet all run inside the main program operating system process, but they are dispatched in a collaborative manner.

# usage g1=gevent.spawn (func,1,,2,3,x=4,y=5) creates a co-object g1,spawn the first argument in parentheses is the function name, such as Eat, which can be followed by multiple arguments, which can be positional arguments or keyword arguments. Are all passed to the function eat g2=# wait for the end   of the G1 # wait for the G2 to end #  or two-step cooperation step: Gevent.joinall ([g1,g2])g1.value# get func1 return value

Automatically switch tasks when IO blocking is encountered

ImportgeventdefEat (name):Print('%s Eat 1'%name) Gevent.sleep (2)    Print('%s Eat 2'%name)defPlay (name):Print('%s Play 1'%name) Gevent.sleep (1)    Print('%s Play 2'%name) G1=gevent.spawn (Eat,'Egon') G2=gevent.spawn (play,name='Egon') G1.join () G2.join ()#or Gevent.joinall ([g1,g2])Print('Master')
Application examples
 fromGeventImportMonkey;monkey.patch_all ()ImportgeventImportRequestsImport Timedefget_page (URL):Print('GET:%s'%URL) Response=requests.get (URL)ifResponse.status_code = = 200:        Print('%d bytes received from%s'%(Len (response.text), url)) start_time=time.time () Gevent.joinall ([Gevent.spawn (Get_page,'https://www.python.org/'), Gevent.spawn (Get_page,'https://www.yahoo.com/'), Gevent.spawn (Get_page,'https://github.com/'),]) Stop_time=time.time ()Print('run time is%s'% (stop_time-start_time)) Application of the process: Crawler

Iv. introduction of IO Model

What is the difference between synchronous (synchronous) IO and asynchronous (asynchronous) Io, what is blocking (blocking) IO and non-blocking (non-blocking) IO respectively? The problem is that different people may give different answers, such as wikis, that asynchronous IO and non-blocking io are a thing. This is because different people have different backgrounds, and the context is not the same when discussing this issue. So, in order to better answer this question, I first limit the context of this article

v. Blocking IO

The "thread pool" or "Connection pool" may alleviate some of the stress, but not all of them, in response to the thousands or even thousands of client requests that may appear in the previous example. In short, multithreaded models can easily and efficiently solve small-scale service requests, but in the face of large-scale service requests, multithreading model will encounter bottlenecks, you can use non-blocking interface to try to solve the problem.

six, non-blocking IO (non-blocking io)
#Service Side fromSocketImport*Import Times=socket (Af_inet,sock_stream) s.bind (('127.0.0.1', 8080)) S.listen (5) s.setblocking (False)#the interface for setting the socket is non-blockingConn_l=[]del_l=[] whileTrue:Try: Conn,addr=s.accept () conn_l.append (conn)exceptBlockingioerror:Print(conn_l) forConninchconn_l:Try: Data=CONN.RECV (1024)                if  notdata:del_l.append (conn)ContinueConn.send (Data.upper ())exceptBlockingioerror:Pass            exceptConnectionResetError:del_l.append (conn) forConninchDel_l:conn_l.remove (conn) conn.close () del_l=[]#Client fromSocketImport*C=socket (Af_inet,sock_stream) c.connect (('127.0.0.1', 8080)) whiletrue:msg=input ('>>:')    if  notMsgContinuec.send (Msg.encode ('Utf-8')) Data=C.RECV (1024)    Print(Data.decode ('Utf-8') ) non-blocking IO instances

But non-blocking IO models are never recommended.

We cannot otherwise have the advantage of being able to do other things while waiting for the task to be completed (including submitting other tasks, that is, "backstage" can have multiple tasks at "" and "").

But it's also hard to hide its drawbacks:

#1. Cyclic invocation of recv () will significantly push up CPU occupancy, which is why we leave a sentence of Time.sleep (2) in the code, otherwise it is very easy to appear on the low-cost host machine. The response latency for task completion is increased because each time a read operation is polled, the task may be completed at any time between polling two times. This can result in a decrease in overall data throughput.

In addition, in this scenario recv () more is to detect the "operation is completed" role, the actual operating system provides more efficient detection "operation is completed" function of the interface, such as select () multiplexing mode, can detect more than one connection is active

Python Day38 coprocessor, io model

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.