zoukankan      html  css  js  c++  java
  • day31

    Event事件

    Event事件
    Event事件的作用:
    - 用来控制线程的执行.
    - 由一些线程去控制另一些线程

    from threading import Event
    
    #实例化
    e = Event()
    
    #如果出现在线程中,则阻塞(False)
    e.wait()
    
    #如果出现在线程中,则则将其他线程中的e.wait()变为True,进入就绪态或运行态
    e.set()
    from threading import Event
    from threading import Thread
    import time
    
    def light():
        print('红灯亮...')
        time.sleep(5)
        # 应该开始发送信号,告诉其他线程准备执行
        e.set()  # 将car中的False ---> True
        print('绿灯亮...')
    
    
    def car(name):
        print('正在等红灯....')
        # 让所有汽车任务进入阻塞态
        e.wait()  # False
        print(f'{name}正在加速漂移....')
    
    
    # 让一个light线程任务 控制多个car线程任务
    t = Thread(target=light)
    t.start()
    
    for line in range(10):
        t = Thread(target=car, args=(f'童子军jason{line}号', ))
        t.start()
    

    线程池和进程池

    1. 什么是进程池与线程池?
      进程池与线程池是用来控制当前程序允许创建(进程/线程)的数量
    2. 进程池与线程池的作用:
      保证在硬件允许的范围内创建 (进程/线程) 的数量
    from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
    import time
    
    pool = ThreadPoolExecutor(5)
    
    def task(res):
        # res == 1
        print('线程任务开始了...')
        time.sleep(1)
        print('线程任务结束了...')
        return 123
    
    #回调函数
    def call_back(res):
        print(type(res))
        # 注意: 赋值操作不要与接收的res同名
        res2 = res.result() #res2 = 123 ,即res2等于task的返回值
        print(res2)
        
    for line in range(5):
        pool.submit(task, 1).add_done_callback(call_back)    #异步提交
        
    # 会让所有线程池的任务结束后,才往下执行代码
    pool.shutdown()
    print('hello')
    

    利用线程池和回调函数爬虫

    协程

    • 进程: 资源单位

      • 线程: 执行单位
      • 协程: 在单线程下实现并发

      注意: 协程不是操作系统资源,他是程序起的名字,为让单线程能实现并发.

      协程的目的:
      - 操作系统:
      多道技术, 切换 + 保存状态

      1. 遇到IO
      2. CPU执行时间过长
      • 协程:
        通过手动模拟操作系统 "多道技术",实现 切换 + 保存状态
        1)手动实现 遇到IO切换, 欺骗操作系统误以为没有IO操作.
        - 单线程 遇到IO, 切换 + 保存状态

              - 单线程 计算密集型, 来回切换 + 保存状态是,反而效率更低
        

        优点:
        在IO密集型的情况下, 会提高效率.

        缺点:
        若在计算密集型的情况下, 来回切换, 反而效率更低

    from gevent import monkey
    monkey.patch_all()  # 可以监听该程序下所有的IO操作
    import time
    from gevent import spawn, joinall  # 用于做切换 + 保存状态
    
    
    def func1():
        print('1')
        # IO操作
        time.sleep(1)
    
    
    def func2():
        print('2')
        time.sleep(3)
    
    
    def func3():
        print('3')
        time.sleep(5)
    
    
    start_time = time.time()
    
    s1 = spawn(func1)
    s2 = spawn(func2)
    s3 = spawn(func3)
    
    # s2.join()  # 发送信号,相当于等待自己 (在单线程的情况下)
    # s1.join()
    # s3.join()
    # 必须传序列类型
    joinall([s1, s2, s3])
    
    end_time = time.time()
    
    print(end_time - start_time)
    
  • 相关阅读:
    从零开始写STL—哈希表
    从零开始写STL-string类型
    从零开始写STL—模板元编程之any
    从零开始写STL—模板元编程之tuple
    c++ 实现 key-value缓存数据结构
    从零开始写STL
    从零开始写STL—functional
    从零开始写STL—set/map
    从零开始写STL-二叉搜索树
    洛谷 P4016 负载平衡问题
  • 原文地址:https://www.cnblogs.com/xwjhyy/p/11735812.html
Copyright © 2011-2022 走看看