zoukankan      html  css  js  c++  java
  • 线程(下)

    线程(下)

    一、队列

    1.1先进先出

    import queue  #导入队列模块
    
    q = queue.Queue(3)  #实例化一个队列对象,允许在里面放入3个数据
    q.put(123)
    q.put('you are my sunshine')
    q.put([1,2,3,4])
    
    print(q.get())
    print(q.get())
    print(q.get())
    
    '''
    123
    you are my sunshine
    [1, 2, 3, 4]
    '''
    

    1.2先进后出(堆栈)

    q = queue.LifoQueue()   #实例化一个队列,这个队列的原则是先进后出
    q.put(123)
    q.put('you are my sunshine')
    q.put([1,2,3,4])
    
    print(q.get())
    print(q.get())
    print(q.get())
    
    '''
    [1, 2, 3, 4]
    you are my sunshine
    123
    '''
    

    1.3 按优先级进出

    q= queue.PriorityQueue(3)  #实例化一个优先级输出数据的队列的对象
    q.put((1,'emmm'))   #括号里面是一个元祖,通常这个元祖的第一个值是int类型
    q.put((2,'emmm'))
    q.put((3,'emmm'))
    
    print(q.get())  #(1, 'emmm')  先输出优先级高的
    
    
    q= queue.PriorityQueue(3)
    q.put((1,'emmm'))   #括号里面是一个元祖
    q.put((1,'aaaa'))
    q.put((3,'emmm'))
    
    print(q.get())  #(1, 'aaaa')   当前面的数字一样时,后面的字符串是按照Ascall码排
    

    二、定时器

    import time
    from threading import Thread,Timer
    
    def task():
        print('线程开始')
        time.sleep(1.5)
        print('线程结束')
    
    t = Timer(3,task)   #3秒之后开启一个线程,也就是说3秒之后打印出来了子线程中的内容
    t.start()
    

    三、线程池与进程池

    ​ 池的功能是限制进程数或线程数,当并发的任务数远远大于计算机所能承受的范围,即无法开启过多的任务数,我们就应该考虑限制进程数或者线程数,从而保证服务器不崩。

    3.1 线程池

    from concurrent.futures import ThreadPoolExecutor
    from threading import currentThread
    import time
    
    def task(i):
        time.sleep(1.5)
        print(f"{currentThread().name}在执行任务{i+1}")
        return i**2
    
    if __name__ == '__main__':
        fu_list = []
        pool = ThreadPoolExecutor(4)  #规定线程池有是个线程
        for i in range(20):  #模拟20个线程,task要做20次,4个线程负责做这个事情
            future = pool.submit(task,i)   #for循环一次,提交一次
            fu_list.append(future)   #先把提交的数据意义放到这个列表里面
        pool.shutdown()   # 关闭池的入口,不让你往里面再放东西
        for fu in fu_list:  #依次循环列表里面的值
            print(fu.result())  #打印返回值
    
    '''
    ThreadPoolExecutor-0_1在执行任务2
    ThreadPoolExecutor-0_0在执行任务1
    ThreadPoolExecutor-0_3在执行任务4
    ThreadPoolExecutor-0_2在执行任务3
    
    ThreadPoolExecutor-0_1在执行任务6
    ThreadPoolExecutor-0_0在执行任务5
    ThreadPoolExecutor-0_2在执行任务7
    ThreadPoolExecutor-0_3在执行任务8
    '''
    .......
    

    3.2 进程池

    from concurrent.futures import ProcessPoolExecutor
    from multiprocessing import current_process
    import time
    
    def task(i):
        time.sleep(1)
        print(f"{current_process().name}在执行任务{i+1}")
        time.sleep(1)
        return i**2
    
    if __name__ == '__main__':
        fu_list = []
        pool = ProcessPoolExecutor(4)  #规定进程池有是个线程
        for i in range(20):  #模拟20个进程,task要做20次,4个进程负责做这个事情
            future = pool.submit(task,i)   #for循环一次,提交一次
            fu_list.append(future)   #先把提交的数据意义放到这个列表里面
        pool.shutdown()   # 关闭池的入口,不让你往里面再放东西
        for fu in fu_list:
            print(fu.result())
            
    '''
    SpawnProcess-1在执行任务1
    SpawnProcess-2在执行任务2
    SpawnProcess-3在执行任务3
    SpawnProcess-4在执行任务4
    
    SpawnProcess-1在执行任务5
    SpawnProcess-2在执行任务6
    SpawnProcess-3在执行任务7
    SpawnProcess-4在执行任务8
    .......
    '''
    

    四、提交任务的两种方式

    4.1 同步

    提交了一个任务,必须等任务执行完 (拿到返回值)才能执行下一行代码

    import os
    import time
    import random
    from multiprocessing import Process
    
    def work(n):
        print(f'{n}: {os.getpid()} is running' )
        time.sleep(random.randint(1,3))
        print('%s:%s is done' %(n,os.getpid()))
    
    if __name__ == '__main__':
        for i in range(3):  #这种就是同步了
            p=Process(target=work,args=(i,))
            p.start()
    

    4.2 异步

    提交了一个任务,不需要等任务执行完 (拿到返回值)才能执行下一行代码,就可以直接执行下一行

    from concurrent.futures import ProcessPoolExecutor
    from multiprocessing import current_process
    import time
    
    def task(i):
        time.sleep(1)
        print(f"{current_process().name}在执行任务{i+1}")
        time.sleep(1)
        return i**2
    
    def parse(future):
        print(future.result())
    
    if __name__ == '__main__':
        fu_list = []
        pool = ProcessPoolExecutor(4)  #规定进程池有是个线程
        for i in range(20):  #模拟20个进程,task要做20次,4个进程负责做这个事情
            future = pool.submit(task,i)   #for循环一次,提交一次
            future.add_done_callback(parse)
            # 为当前任务绑定了一个函数,在当前任务执行结束的时候会触发这个函数,
            # 会把future对象作为参数传给函数
            # 这个称之为回调函数,处理完了回来就调用这个函数.
    
  • 相关阅读:
    mongoose中的versionKey
    Mongodb查询引用
    Mogondb笔记
    jquery.roundabout.js图片叠加3D旋转
    win7下安装curl
    express4.x中路由中间件和挂载路径的关系
    express 设置node_env的环境变量
    ie浏览器不兼容css媒体查询的解决办法
    利用python求解物理学中的双弹簧质能系统详解
    详解用python实现简单的遗传算法
  • 原文地址:https://www.cnblogs.com/yanjiayi098-001/p/11551068.html
Copyright © 2011-2022 走看看