• 协程


    windows:

    当创建进程时,会将当前py文件由上到下重新执行一次,所以我们要将执行代码放在__ main __ 中。

    linux:

    在linux系统中,会直接复制一分代码去执行

    这里有解决问题的办法:
    国内:开源中国,CSDN, cnblods,https://www.v2ex.com/

    国外:Stack Overflow

    GIL: 全局解释器锁

    Cpython的内存管理不是线程安全,在同一进程开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势

    GIL全局解释锁,本质上就是一把互斥锁,保证数据的安全

    GIL全局解释器的优缺点:

    1.优点:

    保证数据的安全

    2.缺点:

    单个进程下,开启多个线程,牺牲执行效率,无法实现并行,只能实现并发

    ,只能实现并发。

    IO密集型,多线程

    计算密集型,多进程

    io密集型任务,每个任务4s

    单核:

    开启的线程比进程节省资源

    多核:

    多线程:

    开启4个子线程:16s

    多进程:

    开启4个进程:16s + 申请开启资源消耗的时间

    计算密集型任务,每个任务4s

    单核:

    开启线程比进程节省资源

    多核:

    多线程:

    开启4个子线程:16s

    多进程:

    开启多个进程:4s

    什么是协程?

    进程:资源单位

    线程:执行单位

    协程: 单线程下实现并发

    在io密集的情况下,使用协程能提高最高效率

    ps:协程不是任何单位,只是一个个程序员臆想出来的东西

    协成的目的是为了:

    手动实现‘遇到io切换+保存状态’去欺骗操作系统,让操作系统误以为没有io操作,将cpu的执行权限给你

    from gevent import monkey  # 猴子补丁
    monkey.patch_all()  # 监听所有的任务是否有io操作
    from gevent import spawn  # 任务
    from gevent import joinall
    import time
    
    
    def task1():
        print('start from task1...')
        time.sleep(1)
        print('end from task1...')
    
    
    def task2():
        print('start from task2...')
        time.sleep(2)
        print('end from task2...')
    
    
    def task3():
        print('start from task3...')
        time.sleep(3)
        print('end from task3...')
    
    
    if __name__ == '__main__':
        start_time = time.time()
        sp1 = spawn(task1)
        sp2 = spawn(task2)
        sp3 = spawn(task3)
        # sp1.start()
        # sp2.start()
        # sp3.start()
        # sp1.join()
        # sp2.join()
        # sp3.join()
        joinall([sp1, sp2, sp3])
    
        end_time = time.time()
    
        print(f'消耗时间:{end_time - start_time}')
    
        start from task1...
    start from task2...
    start from task3...
    end from task1...
    end from task2...
    end from task3...
    消耗时间:3.0070078372955322
    
    线程池与进程池中的回调函数的使用:
    # from gevent import monkey;monkey.patch_all()
    # from gevent import spawn
    # import time
    #
    #
    # def task1(name):
    #     print(name)
    #     print('start')
    #     time.sleep(1)
    #     print('end')
    #
    #
    # def task2():
    #     print('start')
    #     time.sleep(3)
    #     print('end')
    #
    #
    # def task3():
    #     print('start')
    #     time.sleep(5)
    #     print('end')
    #
    # if __name__ == '__main__':
    #     spawn(task1, 'tank')
    #     spawn(task2)
    #     g = spawn(task3)
    #     g.join()
    
    
    # 线程池与进程池
    # 进程池
    # from concurrent.futures import ProcessPoolExecutor
    # import time
    # # 池子对象: 内部可以帮你提交50个启动进程的任务
    # p_pool = ProcessPoolExecutor(50)
    #
    #
    # def task1(n):
    #     print(f'from task1...{n}')
    #     time.sleep(10)
    #
    #
    # if __name__ == '__main__':
    #     n = 1
    #     while True:
    #         # 参数1: 函数名
    #         # 参数2: 函数的参数1
    #         # 参数3: 函数的参数2
    #         # submit(参数1, 参数2, 参数3)
    #         p_pool.submit(task1, n)
    #         n += 1
    
    
    # 线程池
    # from concurrent.futures import ThreadPoolExecutor
    # import time
    # # 池子对象: 内部可以帮你提交50个启动进程的任务
    # p_pool = ThreadPoolExecutor(50)
    #
    #
    # def task1(n):
    #     print(f'from task1...{n}')
    #     time.sleep(10)
    #
    #
    # if __name__ == '__main__':
    #     n = 1
    #     while True:
    #         # 参数1: 函数名
    #         # 参数2: 函数的参数1
    #         # 参数3: 函数的参数2
    #         # submit(参数1, 参数2, 参数3)
    #         p_pool.submit(task1, n)
    #         n += 1
    
    
    # add_done_callback
    # from concurrent.futures import ThreadPoolExecutor
    # import time
    # # 池子对象: 内部可以帮你提交50个启动进程的任务
    # p_pool = ThreadPoolExecutor(50)
    #
    #
    # def task1(n):
    #     print(f'from task1...{n}')
    #     time.sleep(5)
    #     return 'tank'
    #
    #
    # def get_result(obj):
    #     # print(obj.__dict__)
    #     # print(obj._result)
    #     result = obj.result()
    #     print(result)
    #
    #
    # if __name__ == '__main__':
    #     n = 1
    #     while True:
    #         # 参数1: 函数名
    #         # 参数2: 函数的参数1
    #         # 参数3: 函数的参数2
    #         # submit(参数1, 参数2, 参数3)
    #         # add_done_callback(参数1),会将submit提交的task1执行的结果,传给get_result中的第一个参数,第一个参数是一个对象。
    #         p_pool.submit(task1, n).add_done_callback(get_result)
    #         n += 1
    
    
  • 相关阅读:
    DS博客作业02--线性表
    DS博客作业01--日期抽象数据类型设计与实现
    C语言博客作业06--结构体&文件
    C语言博客05--指针
    DS博客作业07--查找
    DS博客作业06--图
    DS博客作业05--树
    DS博客作业03--栈和队列
    DS博客作业02--线性表
    DS博客作业01--日期抽象数据类型设计与实验
  • 原文地址:https://www.cnblogs.com/godlover/p/12018992.html
Copyright © 2020-2023  润新知