• 42 队列 线程池 协程 geven模块 协程完成的socket


    from multiprocessing import Queue,JoinableQueue  # 进程IPC队列
    from queue import Queue # 线程队列 先进先出的
    from queue import LifoQueue # 后进先出的
    put get put_nowait get_nowait full empty qsize
    队列Queue
    先进先出
    自带锁 数据安全
    栈 LifoQueue
    后进先出
    自带锁 数据安全

    后进先出队列
    from queue import LifoQueue
    lq = LifoQueue(5) #超过5个会阻塞
    lq.put(123)
    lq.put(456)
    lq.put('abc')
    lq.put('abc')
    lq.put('abc')
    lq.put('abc')
    lq.put('abc')
    print(lq)
    print(lq.get())
    print(lq.get())
    print(lq.get())
    print(lq.get())
    View Code

    优先级队列

    from queue import PriorityQueue # 优先级队列
    pq = PriorityQueue(5)
    pq.put((10,'aaa'))
    pq.put((5,'zzz'))
    pq.put((5,'bbb'))
    pq.put((20,'ccc'))
    
    print(pq.get())
    print(pq.get())
    print(pq.get())
    print(pq.get())   #前面的值相同的情况下 根据ask排列
    View Code

    ======================线程池===============

    Threading 没有线程池的
    Multiprocessing Pool
    concurrent.futures帮助你管理线程池和进程池

    import time
    from threading import currentThread,get_ident
    from concurrent.futures import ThreadPoolExecutor #帮你开启线程池中的类
    from concurrent.futures import ProcessPoolExecutor  #帮你开启进程池中的类
    
    def  func(i):
        time.sleep(1)
        print("in %s  %s" %(i,currentThread()))
        return i**2
    def back(fn):
        print(fn.result(),currentThread())
    
    
    t=ThreadPoolExecutor(5)
    t.map(func,range(20)) #启动多线程任务
    """相当于
    for i in range(20):
            t.submit(func,i)
    """
    t = ThreadPoolExecutor(5)
    for i in range(20):
        t.submit(fn=func,)
    t.shutdown()
    print('main : ',currentThread())
    View Code

    获取任务的结果

    import time
    from threading import currentThread,get_ident
    from concurrent.futures import ThreadPoolExecutor #帮你开启线程池中的类
    from concurrent.futures import ProcessPoolExecutor  #帮你开启进程池中的类
    
    def  func(i):
        time.sleep(1)
        print("in %s  %s" %(i,currentThread()))
        return i**2
    def back(fn):
        print(fn.result(),currentThread())
    
    
    # t = ThreadPoolExecutor(20)
    # ret_l = []
    # for i in range(20):
    #     ret = t.submit(func,i)
    #     ret_l.append(ret)
    # t.shutdown()
    # for ret in ret_l:
    #     print(ret.result())
    # print('main : ',currentThread())
    View Code

    回调函数

    import time
    from threading import currentThread,get_ident
    from concurrent.futures import ThreadPoolExecutor #帮你开启线程池中的类
    from concurrent.futures import ProcessPoolExecutor  #帮你开启进程池中的类
    
    def  func(i):
        time.sleep(1)
        print("in %s  %s" %(i,currentThread()))
        return i**2
    def back(fn):
        print(fn.result(),currentThread())
    
    
    t=ThreadPoolExecutor(20)
    for i  in range(100):
        t.submit(func,i).add_done_callback(back)
    View Code

    回调函数  (进程版)

    import os
    import time
    from concurrent.futures import ProcessPoolExecutor #开启进程的类
    
    def  func(i):
        time.sleep(1)
        print("in %s  %s" %(i,os.getpid()))
        return i**2
    
    def back(fn):
        print(fn.result(),os.getpid())
    if __name__ == '__main__':
        print("main:",os.getpid())
        t = ProcessPoolExecutor(20)
        for i in range(100):
            t.submit(func, i).add_done_callback(back)
    View Code
    multiprocessing模块自带进程池的
    # threading模块是没有线程池的
    # concurrent.futures 进程池 和 线程池
        # 高度封装
        # 进程池/线程池的统一的使用方式
    # 创建线程池/进程池  ProcessPoolExecutor  ThreadPoolExecutor
    # ret = t.submit(func,arg1,arg2....)  异步提交任务
    # ret.result() 获取结果,如果要想实现异步效果,应该是使用列表
    # map(func,iterable)
    # shutdown close+join 同步控制的
    # add_done_callback 回调函数,在回调函数内接收的参数是一个对象,需要通过result来获取返回值
        # 回调函数仍然在主进程中执行
    # 概念性的面试题
    # web框架
    # 爬虫/自动化开发
    # 爬虫 : 访问大量的网页,对网页代码进行处理
        # 正则表达式
        # 字符串处理
        # 前端
        # 并发
    # 运维 : 一堆机器 一堆程序 你去维护
    # 自动化开发/运维开发 : 开发一些程序 让机器的维护/程序的维护自动化起来
        # 运维基础
        # python的基础开发
        # 并发
        # 前端
    # 进程 + 线程  = 100个并发
        # 4-5个进程
        # 每个进程中 开 20个线程
    =========================协程====================================
    进程:cpu最小的资源分配单位
    线程:cpu最小的调度单位
    协程:线程分成八半儿
    CPpython线程是不能利用多核的,多个线程无法利用多核,但一个线程能同时执行多个任务
    协程: 能在一条线的基础上,在多个任务之间相互转换
    节省了线程代码的消耗
    是从python代码的级别调度的
      正常的线程是cpu调度的最小单位
      协程的调度并不是由操作系统来完成的
    实例1:在两个任务之间的互相转换
    def func():
        print(1)
        x = yield 'aaa'
        print(x)
        yield 'bbb'
    
    g = func()
    print(next(g))
    print(g.send('****'))
    View Code

    在多个函数之间互相切换的功能---协程   yeild 只有程序之间的切换,没有重利用任何IO操作的时间

    def consumer():
        while True:
            x=yield
    
            print(x)
    def producer():
        g=consumer()
        next(g)
        for i in range(10):
            g.send(i)
    producer()
    View Code

    # 程序执行的上下文切换的工具
    # greenlet 程序上下文切换的
    # 模块的安装
    # 别人写好的代码
        # sys.path
        # 把别人写好的代码 放到sys.path指示的路径下面
        # python2/python3
        # pip python2
        # pip3 python3
        # pip3 install 要安装的模块的名字    在cmd直接打印即可
        # pip3 install greenlet
        # pip3 install django

    # pip3 install greenlet
    # pycharm装
    # 重新配环境变量  cmd要重启
    # 重新装python
    # 重新配置环境变量


     协程模块  # 单纯的程序切换耗费时间

    from greenlet import greenlet
    import time
    def eat():
        print('')
        time.sleep(1)
        g2.switch()  # 切换
        print('吃完了')
        time.sleep(1)
        g2.switch()
    
    def play():
        print('玩儿')
        time.sleep(1)
        g1.switch()
        print('玩儿美了')
        time.sleep(1)
    
    g1 = greenlet(eat)
    g2 = greenlet(play)
    g1.switch()   # 切换
    View Code
    遇到IO就切换
    gevent    pip3 install gevent
    greenlet是gevent的底层
    gevent是基于greenlet实现的
    python代码在控制程序的切换
    python版本管理的重要性
        virtualenv
        pipenv
    ===========================gevent模块=====================
    import gevent
    
    import time
    def eat():
        print('')
        time.sleep(2)
        print('吃完了')
    def play():
        print('玩儿')
        time.sleep(1)
        print('玩儿美了')
    g1 = gevent.spawn(eat)
    g2 = gevent.spawn(play)
    gevent.joinall([g1,g2])
    """
    g1.join()
    g2.join()
    """
    View Code

     g1.join()
    # g2.join()
    # 没执行
    # 为什么没执行???是需要开启么?
    # 没有开启但是切换了
        # gevent帮你做了切换,做切换是有条件的,遇到IO才切换
        # gevent不认识除了gevent这个模块内以外的IO操作
        # 使用join可以一直阻塞直到协程任务完成
    # 帮助gevent来认识其他模块中的阻塞
        # from gevent import monkey;monkey.patch_all()写在其他模块导入之前

    ======================协程完成的socket通信================
    server端
    from gevent import monkey;monkey.patch_all()
    import socket
    import gevent
    def talk(conn):
        while True:
            conn.send(b'hello')
            print(conn.recv(1024))
    
    sk = socket.socket()
    sk.bind(('127.0.0.1',9090))
    sk.listen()
    while True:
        conn,addr = sk.accept()
        gevent.spawn(talk,conn)
    View Code

    client端

    import  socket
    from threading import Thread
    def client():
        sk = socket.socket()
        sk.connect(('127.0.0.1',9090))
        while True:
            print(sk.recv(1024))
            sk.send(b'bye')
    
    for i in range(500):
        Thread(target=client).start()
    View Code


    # 协程 能够在单核的情况下 极大地提高CPU的利用率
        # 不存在数据不安全
        # 也不存在线程切换创造的时间开销
        # 切换是用户级别的,程序不会因为协程中某一个任务进入阻塞状态而使整条线程阻塞
    # 线程的切换
        # 时间片到了  降低CPU的效率
        # IO会切      提高CPU效率

  • 相关阅读:
    box-shadow 用法总结
    CSS绘制三角形
    js实现限制容器中字符个数
    解决 IE 或者兼容模式不支持 document.getElementsByClassName() 的方法
    JavaScript获取浏览器高度和宽度值(documentElement,clientHeight,offsetHeight,scrollHeight,scrollTop,offsetParent,offsetY,innerHeight)
    appium-python-api中文文档
    通过adb获取应用的Activity堆栈信息
    小米手机连接adb只显示List of devices attached
    关于如何等待一个元素的出现而不用一些笨拙粗暴的time.sleep()方法
    Appium环境搭建
  • 原文地址:https://www.cnblogs.com/daien522556/p/9397204.html
Copyright © 2020-2023  润新知