zoukankan      html  css  js  c++  java
  • python 线程(其他方法,队列,线程池,协程 greenlet模块 gevent模块)

    1.线程的其他方法

    from threading import Thread,current_thread
    import time
    import threading
    def f1(n):
        time.sleep(1)
        print('子线程名称',current_thread().getName())#获取线程名
    if __name__=='__main__':
        t1=Thread(target=f1,args=(1,))
        t1.start()
        print('主线程名称',current_thread().getName())
        print('主进程id',current_thread().ident)
        print(current_thread())#当前线程的对象
        print(threading.enumerate())#当前正在运行的线程的一个列表
        print(threading.active_count())#当前正在运行的线程的数量
    #########结果########
    主线程名称 MainThread
    主进程id 7512
    <_MainThread(MainThread, started 7512)>
    [<_MainThread(MainThread, started 7512)>, <Thread(Thread-1, started 5680)>]
    2
    子线程名称 Thread-1

    2.线程队列

    import queue
    ###先进先出
    q=queue.Queue(3)
    q.put(1)
    q.put(2)
    print('当前队列内容长度',q.qsize())
    q.put(3)
    print('查看队列是否满了',q.full())
    
    print(q.get())
    print(q.get())
    print('查看队列是否为空',q.empty())
    print(q.get())#在多打一个get会形成程序阻塞
    print('查看队列是否为空',q.empty())
    try:
        q.get_nowait()#报错queue.Empty
    except Exception:
        print('队列空了')
    ############################
    当前队列内容长度 2
    查看队列是否满了 True
    1
    2
    查看队列是否为空 False
    3
    查看队列是否为空 True
    队列空了
    ####先进后出 类似于栈
    import queue
    q = queue.LifoQueue(3)
    #
    q.put(1)
    q.put(2)
    q.put(3)
    print(q.get())
    print(q.get())
    print(q.get())
    ##############
    3
    2
    1
    ####优先级队列
    import queue
    q=queue.PriorityQueue(5)
    q.put((5,'alex'))
    q.put((2,'宝宝'))
    q.put((4,'大力'))
    print(q.get())
    print(q.get())
    print(q.get())
    ##########
    (2, '宝宝')
    (4, '大力')
    (5, 'alex')
    #如果优先级数字相同,如果数据类型不同会报错,类型相同会对比元祖中的第二行英语字母

    3.线程池

    map方法

    import time
    from concurrent.futures import ThreadPoolExecutor
    from threading import current_thread
    
    def func(n):
        time.sleep(1)
        print(n)
        # print(n,current_thread().ident)
    
    if __name__ == '__main__':
        t_p = ThreadPoolExecutor(4)
        map_res = t_p.map(func,range(10))   #异步执行的,map自带join功能
        print(map_res)
        print([i for i in map_res])
    #######################
    <generator object Executor.map.<locals>.result_iterator at 0x00000000029E94F8>
    012
    
    3
    
    4
    5
    6
    7
    89
    [None, None, None, None, None, None, None, None, None, None]#会取不到值
    concurrent.futures 写法
    import time
    from threading import current_thread
    from concurrent.futures import  ThreadPoolExecutor,ProcessPoolExecutor
    def func(n):
        time.sleep(0.1)#此处等待一秒是为了将取值时候的打印结果进行区分
        # print(n)
        return n
    if __name__ == '__main__':
        t_p = ThreadPoolExecutor(4)#可以进行线程进程切换
        # t_p=ProcessPoolExecutor(4)
        t_res_lst = []
        for i in range(10):
            res_obj =t_p.submit(func,i)   #提交执行函数,返回一个结果对象,i作为任务函数的参数
            t_res_lst.append(res_obj)
        t_p.shutdown()  #起到原来的close阻止新任务进来 + join的作用,等待所有的线程执行完毕
        # print("t_res_lst",t_res_lst)      #<Future at 0x1fa10a43400 state=finished returned int> 加了shutdown后全部变为finished
                                          #<Future at 0x19d37f5c7f0 state=running>, <Future at 0x19d37f5c9b0 state=pending>不加shutdo时
        for e_res in t_res_lst:
            print(e_res.result())
        # t_p.shutdown()
    #在不加shutdown时,主线程在循环列表时,也是每一个进行取值,
    # 但是由于可以有四个对象可以一起取值,(拿前四个为例,)
    # 也就是当列表循环到4个时此时会等待将近1s
    # 因为在执行函数有停留,但线程池可以四个同时执行,因此会有4个结果一起出来
    #但是当加了shutdown时,此时线程会全部执行完毕,然后在列表里是,此时的对象已经全部执行完毕
    ########################
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9

    4.协程

    协程本质上就是一个线程,以前线程任务的切换是由操作系统控制的,遇到I/O自动切换,在我们自己的程序里面来控制任务的切换。
    现在我们用协程的目的就是较少操作系统切换的开销(开关线程,创建寄存器、堆栈等,在他们之间进行切换等),

    import gevent
    from gevent import monkey;monkey.patch_all()#本身不认识其他模块中的IO操作,但是如果我们在导入其他模块之前执行 就能够认识
    import time

    def f1(): print('第一次f1') # print(threading.current_thread().getName()) # gevent.sleep(1) time.sleep(2) print('第二次f1') def f2(): # print(threading.current_thread().getName()) print('第一次f2') # gevent.sleep(2) time.sleep(2) print('第二次f2') s = time.time() g1 = gevent.spawn(f1) #异步提交了f1任务 g2 = gevent.spawn(f2) #异步提交了f2任务 # g1.join() # g2.join() gevent.joinall([g1,g2]) e = time.time() print('执行时间:',e-s) print('主程序任务') ####################### 第一次f1 第一次f2 第二次f1 第二次f2 执行时间: 2.0021142959594727 主程序任务

    下面是理解 :可看 可不看

    #####生成器写法
    import time
    def f1():
        for i in range(2):
            time.sleep(0.5)
            print('f1>>',i)
            yield
    def f2():
        g = f1()
        for i in range(2):
            time.sleep(0.5)
            print('f2>>', i)
            next(g)
    f1()
    f2()
    ############
    f2>> 0
    f1>> 0
    f2>> 1
    f1>> 1
    #######greenlet模块
    import time
    from greenlet import greenlet
    def f1(s):
        print('第一次f1'+s)
        g2.switch('taibai')  #切换到g2这个对象的任务去执行
        time.sleep(1)
        print('第二次f1'+s)
        g2.switch()
    def f2(s):
        print('第一次f2'+s)
        g1.switch()
        time.sleep(1)
        print('第二次f2'+s)
    g1 = greenlet(f1)  #实例化一个greenlet对象,并将任务名称作为参数参进去
    g2 = greenlet(f2)
    g1.switch('alex') #执行g1对象里面的任务
    ###########
    #首先会执行g1的switch(alex)也就是执行f1 print('第一次f1'+alex)
    #往下就会执行f2 进行传参taibai 会打印 第一次f2taibai
    #往下 执行了g1也就是f1  print('第二次f1'+s)
    #往下继续走  print('第二次f2'+taibai)
    ##########结果
    第一次f1alex
    第一次f2taibai
    第二次f1alex
    第二次f2taibai

     回调函数

    #######回调函数
    from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
    def f1(n,s):
        return n+s
    def f2(n):
        print('回调函数>>',n.result())
    if __name__ == '__main__':
        tp=ThreadPoolExecutor(4)
        res=tp.submit(f1,11,12).add_done_callback(f2)
    #####################
    回调函数>> 23
    不怕大牛比自己牛,就怕大牛比自己更努力
  • 相关阅读:
    aptana中删除空行
    css预处理的引入与问题
    rsyslog 服务器重启后 发现不能接受到外部日志 只能接受本地日志 关闭防火墙即可
    php访问其他网站接口
    mysql 表查询结果 总行数计算
    linux centos 恢复 还原 备份 Snapper 快照说明
    linux 服务 启动 关闭 列表
    linux yum 安装 卸载
    php7 mysql_pconnect() 缺失 解决方法
    搭建一个免费的,无限流量的Blog----github Pages和Jekyll入门
  • 原文地址:https://www.cnblogs.com/zaizai1573/p/10268691.html
Copyright © 2011-2022 走看看