• Python9-IO模型-day41


    # 进程:启动多个进程,进程之间是由操作系统负责调用
    # 线程:启动多个线程,真正由被cpu执行的最小单位实际是线程
    # 开启一个线程,创建一个线程,寄存器、堆栈
    # 关闭一个线程
    # 协程
    # 本质上是一个线程
    # 能够在多个任务之间来切换来节省一些IO时间
    # 协程中任务之间的切换也消耗时间,但是开销要远远小于进程和线程之间的切换
    # 实现并发的手段
    def consumer():
       while True:
            x = yield
            print('处理了数据:',x)
    
    def producer():
        c = consumer()
        next(c)
        for i in range(10):
            print('生成了数据:',i)
            c.send(i)
    producer()
    # 真正的协程模块就是使用greenlet完成的切换
    
    from greenlet import greenlet
    
    def eat():
        print('eating start')
        g2.switch()
        print('eating end')
        g2.switch()
    def play():
        print('playing start')
        g1.switch()
        print('playing end')
    g1 = greenlet(eat)
    g2 = greenlet(play)
    g1.switch()
    from gevent import monkey;monkey.patch_all()
    import time
    import gevent
    def eat():
        print('eating start')
        time.sleep(1)
        print('eating end')
    
    def play():
        print('playing start')
        time.sleep(1)
        print('playing end')
    g1 = gevent.spawn(eat)
    g2 = gevent.spawn(play)
    g1.join()
    g2.join()
    # 同步和异步的列子
    from gevent import monkey;monkey.patch_all()
    import time
    import gevent
    def task():
        time.sleep(1)
        print(12345)
    def sync():
        for i in range(10):
            task()
    def async():
        g_lst = []
        for i in range(10):
            g = gevent.spawn(task)
            g_lst.append(g)
        gevent.joinall(g_lst)
    sync()
    async()
    # 协程:能够在一个线程中实现并发效果的概念
    # 依赖于能够规避一些在任务中的IO操作
    # 在任务的执行过程中检测到io就切换到其他任务
    # 爬虫的例子
    # 请求过程中的IO等待
    from gevent import  monkey;monkey.patch_all()
    import gevent
    from  urllib.request import urlopen
    def get_url(url):
        response = urlopen(url)
        content = response.read().decode('utf-8')
        return len(content)
    
    g1 = gevent.spawn(get_url,'http://www.baidu.com')
    g2 = gevent.spawn(get_url,'http://www.taobao.com')
    g3 = gevent.spawn(get_url,'http://www.sougou.com')
    g4 = gevent.spawn(get_url,'http://www.hao123.com')
    g5 = gevent.spawn(get_url,'http://www.cisco.com')
    g6 = gevent.spawn(get_url,'http://www.cnblogs.com')
    gevent.joinall([g1,g2,g3,g4,g5,g6])
    print(g1.value)
    print(g2.value)
    print(g3.value)
    print(g4.value)
    print(g5.value)
    print(g6.value)

     socket-协程

    #server
    from
    gevent import monkey;monkey.patch_all() import socket import gevent def talk(conn): conn.send(b'hello') print(conn.recv(1024).decode('utf-8')) conn.close() sk = socket.socket() sk.bind(('127.0.0.1',8080)) sk.listen() while True: conn,addr = sk.accept() gevent.spawn(talk,conn) sk.close()
    #client
    import
    socket sk = socket.socket() sk.connect(('127.0.0.1',8080)) print(sk.recv(1024)) msg = input('>>>>').encode('utf-8') sk.send(msg) sk.close()
    协程 在一个线程上,提高cpu的利用率
    # 协程相比多线程的优势。切换效率提高了
    # 同步:提交一个任务之后要等待这个任务执行完毕;
    # 异步:只管提交任务;不等待这个任务执行完毕就可以做其他事情
    # 阻塞:recv recvfrom accept
    # 非阻塞

    # 阻塞 运行状态---阻塞状态---就绪状态

    非阻塞IO方式实现socke#server

    #server
    import socket
    sk = socket.socket()
    sk.bind(('127.0.0.1',8080))
    sk.setblocking(False)
    sk.listen()
    conn_l = []
    del_conn = []
    while True:
    try:
    conn,addr = sk.accept() #不阻塞,但是没有连我会报错
    print('建立连接!',addr)
    conn_l.append(conn)

    except BlockingIOError:
    for con in conn_l:
    try:
    msg = con.recv(1024) #非阻塞,如果没有数据就报错
    if msg == b'':
    del_conn.append(con)
    continue
    print(msg)
    conn.send(b'byebye')
    except BlockingIOError:pass
    for con in del_conn:
    conn.close()
    conn_l.remove(con)
    del_conn.clear()
     
    #client
    import time
    import  socket
    import threading
    def func():
        sk = socket.socket()
        sk.connect(('127.0.0.1',8080))
        sk.send(b'hello')
        time.sleep(1)
        print(sk.recv(1024))
        sk.close()
    for i in range(20):
        threading.Thread(target=func).start()

     

     

    IO多路复用-socket
    #server
    import socket
    import select
    sk = socket.socket()
    sk.bind(('127.0.0.1',8080))
    sk.setblocking(False)
    sk.listen()
    read_lst = [sk]
    while True:
        r_lst,w_lst,x_lst = select.select(read_lst,[],[])
        for i in r_lst:
            if i is sk:
                conn,addr = i.accept()
                read_lst.append(conn)
            else:
                ret = i.recv(1024)
                if ret == b'':
                    i.close()
                    read_lst.remove(i)
                    continue
                print(ret)
                i.send(b'bybybybyby')
    #client
    import time
    import  socket
    import threading
    def func():
        sk = socket.socket()
        sk.connect(('127.0.0.1',8080))
        sk.send(b'gogogog')
        time.sleep(3)
        print(sk.recv(1024))
        sk.close()
    for i in range(20):
        threading.Thread(target=func).start()
  • 相关阅读:
    【Ubuntu】Ubuntu使用root登录
    【Ubuntu】在Ubuntu 12.04 LTS上安装JDK6
    2012/12/18 水曜日 感怀
    【Ubuntu】Ubuntu Java aptget安装配置
    GRUB,分区,menu.ls,(hd0,1)【转载】
    【ExtJS】错误:this.config[...].width为空或不是对象
    【Ubuntu】Ubuntu常用文件操作命令
    Win7 64bit OS 安装64bit JDK后 不能安装Spket IDE
    IE中控制焦点(asp.net)
    mac os里各种启动参数的含义
  • 原文地址:https://www.cnblogs.com/zhangtengccie/p/10423525.html
Copyright © 2020-2023  润新知