网络编程-----协程

Posted systemsystem

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络编程-----协程相关的知识,希望对你有一定的参考价值。

概念:

    

  python的线程属于内核级别的,即由操作系统控制调度
(如单线程遇到io或执行时间过长就会被迫交出cpu执行权限,切换其他线程运行) 
 单线程内开启协程,一旦遇到io,就会从应用程序级别
( 而非操作系统)控制切换,以此来提升效率(!!!非io操作的切换与效率无关)

  协程:  (简单来说就是单线程下的并发).

       指的是只在同一条线程上能够相互切换多个任务,

     遇到IO就切换实际上是我们利用协程提高工作效率的一种工作方式.

  特点:   

     (纤程,轻型线程)

     协程是操作系统级别的操作单位

     协程的切换开销更小,属于程序级的切换,对于操作系统来说是不可见的,不需要操作系统调                 度   

线程内就可以实现并发的效果,最大限度地利用cpu
   修改共享数据不需要加锁

  他的效率如何?

     和操作系统本身没有关系,和线程也没有关系.

     而是看程序的调度是否合理

     缺点:

             协程的本质是单线程下,无法利用多核,所以他的顺序为(一个程序开启多个进程,每个进程开启多个线程,每个线程开启协程)

    协程指的是单个线程,因而一旦协程出现阻塞,将会阻塞整个线程.

 

协程模块:

  greelet:在多个任务之间来回切换 

  gevent ;也是多个任务之间切换(比上边的更强大)

用法:

import time

from greenlet import greenlet
‘‘‘
def play():#协程1
    print(娃哈哈)
    g2.switch()
    print(托儿索)
    g2.switch()
def sleep(): # 协程2
    print(喜之狼)
    g1.switch()
    print(儿童劫)
g1=greenlet(play)
g2=greenlet(sleep)
g1.switch()
‘‘‘
import gevent
def play():#协程1
    print(娃哈哈)
    gevent.sleep(0.3)
    print(托儿索)

def sleep(): # 协程2
    print(喜之狼)
    gevent.sleep(0.2)
    print(儿童劫)

g1=gevent.spawn(play)
g2=gevent.spawn(sleep)
# g1.join(0.5) # 阻塞0.5秒
# g2.join()#           #  精准的控制协程任务,一定是执行完毕之后join立即结束阻塞
print(哈哈)
gevent.joinall([g1,g2])


from gevent import monkey;monkey.patch_all()  # 把下面所有的模块中的阻塞都打成一个包,然后gevent就可以识别这些阻塞事件了
import time
import gevent
def play():   # 协程1
    print(time.time())
    print(start play)
    time.sleep(1)
    print(end play)
def sleep():  # 协程2
    print(start sleep)
    time.sleep(1)
    print(end sleep)
    print(time.time())

g1 = gevent.spawn(play)
g2 = gevent.spawn(sleep)
gevent.joinall([g1,g2])

协程下实现socekt通信:

服务端:
from
gevent import monkey;monkey.patch_all() import socket import gevent def talk(conn): while True: msg = conn.recv(1024).decode() conn.send(msg.upper().encode()) sk = socket.socket() sk.bind((127.0.0.1,9000)) sk.listen() while True: conn,addr = sk.accept() gevent.spawn(talk,conn) 客户端: import socket import threading def task(): sk = socket.socket() sk.connect((127.0.0.1,9000)) while True: sk.send(bhello) print(sk.recv(1024)) for i in range(500): threading.Thread(target=task).start()

 






以上是关于网络编程-----协程的主要内容,如果未能解决你的问题,请参考以下文章

网络IO解决方案 — 协程框架的实现

两种方式封装Retrofit+协程,实现优雅快速的网络请求

两种方式封装Retrofit+协程,实现优雅快速的网络请求

“按史索骥”:Python异步编程之协程进化史

Python协程&asyncio&异步编程

重修课程day35(网络编程九之协程)