博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
协程,IO模式
阅读量:4308 次
发布时间:2019-06-06

本文共 3928 字,大约阅读时间需要 13 分钟。

1、协程(别人的模块,达到单线程并发效果)

程序的运行状态:

阻塞:

IO阻塞

非阻塞:

运行

就绪

单线程实现并发:

在应用程序里控制多个任务的切换+保存状态

可以把IO减下来,但是不可能降到无

优点:

应用程序级别速度要远远高于操作系统的切换

缺点:

多个任务一旦有一个阻塞没有切,整个县城都堵塞在原地

该线程内的其他的任务都不能执行

 

一旦引入协程,就需要检测单线程下素有的IO行为,

实现遇到IO就切换,少一个都不行,因为一旦一个任务阻塞,整个线程就 阻塞,其他的任务即便是可以计算,但是也无法运行。

2、用协程的目的

想要在单线程下实现并发

并发指的是多个任务看起来是同时运行的

并发=切换+保存状态

线程在进程内,进程在操作系统内,一切由操作系统控制

 

自己设置python程序让线程形成切换,不用操作系统控制。

协程只有单线程下遇到IO切换才会提成效率,操作系统相对与协程要更慢点

 

import timedef func1():    for i in range(1000000):        i+1def func2():    for i in range(1000000):        i+1start = time.time()func1()func2()stop=time.time()print(stop-start)# 基于yield并发import timedef func1():    while True:        print("func1")        yielddef func2():    g=func1()    for i in range(1000000):        print("func2")        i+1        time.sleep(3)        next(g)start=time.time()func2()stop=time.time()print(stop-start)
串行执行:

 

from gevent import monkey,spawn;monkey.patch_all()#monkey.patch_all()补丁import timedef eat(name):    print("%s eat 1" %name)    time.sleep(3)    print("%s eat 2" %name)def play(name):    print("%s play 1" %name)    time.sleep(1)    print("%s play 2" %name)start=time.time()g1=spawn(eat,"yf")#自动运行任务 模块g2=spawn(play,"fxc")g1.join()#通过补丁让join识别其他IOg2.join()print(time.time() - start)print(g1)print(g2)from gevent import monkey,spawn;monkey.patch_all()from threading import current_threadimport timedef eat(name):    print("%s eat 1" %current_thread().name)#都是一个线程,前面有dummy假标明    time.sleep(3)    print("%s eat 2" %current_thread().name)def play(name):    print("%s play 1" %current_thread().name)    time.sleep(1)    print("%s play 2" %current_thread().name)start=time.time()g1=spawn(eat,"yf")g2=spawn(play,"fxc")g1.join()g2.join()print(time.time() - start)print(g1)print(g2)
与yield类似可以直接计算的 gevent

并发的套接字通信:

from gevent import spawn,monkey;monkey.patch_all()from socket import *from threading import Threaddef talk(conn):    while True:        try:            data = conn.recv(1024)            if len(data)==0:break            conn.send(data.upper())        except ConnectionResetError:            break    conn.close()def server(ip,port,backlog=5):    server = socket(AF_INET,SOCK_STREAM)    server.bind((ip,port))    server.listen(backlog)    print("starting..")    while True:        conn,addr=server.accept()        spawn(talk,conn)if __name__ == '__main__':    g=spawn(server,"127.0.0.1",8080)    g.join()
服务器:
from threading import Thread,current_threadfrom socket import *def task():    client = socket(AF_INET,SOCK_STREAM)    client.connect(("127.0.0.1",8080))    while True:        msg="%s say hello" %current_thread().name        client.send(msg.encode("utf-8"))        data=client.recv(1024)        print(data.decode("utf-8"))if __name__ == '__main__':    for i in range(500):        t=Thread(target=task)        t.start()
客户端:

网络IO:

    recvfrom:#等待客户链接请求

        wait data:等待客户端产生数据——》客户端OS--》网络--》服务端操作系统缓存

        copy data:由本地操作系统缓存中的数据拷贝到应用程序的内存中

 

    send:

        copy data

conn.recv(1024) ==>OS

from socket import *import timeserver = socket()server.bind(("127.0.0.1",8080))server.listen(5)server.setblocking(False)#是否有链接过来conn_l=[]while True:    try:        print("总连接数[%s]" %len(conn_l))        conn,addr=server.accept()        conn_l.append(conn)    except BlockingIOError:        del_l=[]        for conn in conn_l:            try:                data=conn.recv(1024)                if len(data)==0:                    del_l.append(conn)                    continue                conn.send(data.upper())            except BlockingIOError:                pass            except ConnectionResetError:                del_l.append(conn)        for conn in del_l:            conn_l.remove(conn)
服务端:
from socket import *import osclient=socket(AF_INET,SOCK_STREAM)client.connect(("127.0.0.1",8080))while True:    msg="%s say hello" %os.getpid()    client.send(msg.encode("utf-8"))    data=client.recv(1024)    print(data.dacoda("utf-8"))
客户端:

 

转载于:https://www.cnblogs.com/yf18767106368/p/9325944.html

你可能感兴趣的文章
并发编程实战(一)
查看>>
SharePoint 自定义WebPart之间的连接
查看>>
实现 laravel 的artisan
查看>>
python bool值要注意的一些地方
查看>>
ZOJ 2165 Red and Black
查看>>
在配置静态IP的时候遇到 :bringing up interface eth0 : error unknown connection
查看>>
Android版CCLabelTTF在setstring时出现黑块
查看>>
【10.20校内测试】【小模拟】【无向图建树判奇偶环】【树上差分】
查看>>
Quartz任务调度
查看>>
用python发送email
查看>>
Linux文件系统
查看>>
C# 与java区别总结 收集
查看>>
linux 安装jdk
查看>>
mongo文档操作
查看>>
HTTP协议
查看>>
【循序渐进学Python】6.Python中的函数
查看>>
django ORM中的RelatedManager(关联管理器)
查看>>
VA Code编写html(1)
查看>>
C# winForm 定时访问PHP页面小工具
查看>>
编写TreeSet类的实现程序,其中相关的迭代器使用二叉查找树
查看>>