zoukankan      html  css  js  c++  java
  • python并发编程之线程剩余内容(线程队列,线程池)及协程

    1. 线程的其他方法

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

    2. 线程队列 

    线程队列中三种队列形式,所使用的方法相同,都有put(),get(),put_nowait(),get_nowait(),qsize(),full(),empty() 等这些方法.就只传一组先进先出的代码

    import queue

    先进先出队列:queue.Queue(n)

    q = queue.Queue(3)
    q.put(1)
    q.put(2)
    print('当前队列内容长度',q.qsize())
    q.put(3)
    print('查看队列是否满了',q.full())
    
    try:
        q.put_nowait(4)  
    except Exception:
        print('队列满了')
    
    print(q.get())
    print(q.get())
    print(q.get())
    print('查看队列是否为空',q.empty())
    
    try:
        q.get_nowait()  
    except Exception:
        print('队列空了')

    先进后出 / 后进先出队列:queue.LifoQueue(n) 

    优先级队列:

    queue.priorityQueue(n)

      优先级队列中如果第一个参数相同,后面的比较方法为下面的描述.

      如果说值里面的元素是数字类型,那么当两个值的优先级相同时,比较的是两个值的大小,小的优先被取出来.如果元素是字符串,那么依次比较每个字母的ascii表中的位置,小的优

    先被取出来.如果put的数据是一个元组,元组的第一个参数是优先级数字,数字越小优先级越高,越先被get到被取出来,第二个参数是put进去的值,如果说优先级相同,那么值别忘了应

    该是相同的数据类型,字典不行

    3. 线程池

    from concurrent_futures import ThreadPoolExecutor,ProcessPoolExecutor

    p = ThreadPoolExecutor(4)  #默认的线程个数是cpu个数 * 5

    p = ProcessPoolExecutor(4)  #默认的进程个数是cpu个数

    map(f1,可迭代对象)  : 异步提交任务

    sublim(f1,参数)  : 异步提交任务,和get方法一样,如果没有结果,会等待,阻塞程序

    shutdown()  : 锁定线程池,等待线程池中所有已经提交的任务全部执行完毕 , 相当于close + join

    import time
    from threading import current_thread
    from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
    
    def f1(n,s):
        time.sleep(1)
        # print('%s号子线程'%current_thread().ident)
        # print(n,s)
        return
    
    if __name__ == '__main__':
    
        tp = ThreadPoolExecutor(4)
        # tp = ProcessPoolExecutor(4)
        # tp.map(f1,range(10))  #异步提交任务,参数同样是任务名称,可迭代对象
        res_list = []
        for i in range(10):
            res = tp.submit(f1,i,'baobao')  #submit是给线程池异步提交任务,
            print(res)
            # res.result()
            res_list.append(res)
    
        for r in res_list:
            print(r.result())
    
        tp.shutdown()  #主线程等待所有提交给线程池的任务,全部执行完毕 close + join
        # for r in res_list:
        #     print(r.result())
        print('主线程结束')

     线程池回调函数

      线程池的回调函数与进程池的相似

    import time
    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)

    4. 协程

    生成器版

    import time
    
    def f1():
        for i in range(10):
            time.sleep(0.5)
            print('f1=>',i)
            yield
    
    def f2():
        g = f1()
        for i in range(10,20):
            time.sleep(0.5)
            print('f2=>', i)
            next(g)
    
    f1()
    f2()

    greenlet模块

    import time
    from greenlet import greenlet
    
    def f1():
        print('第一次f1')
        g2.switch()  #切换到g2这个对象的任务去执行
        time.sleep(1)
        print('第二次f1')
        g2.switch()
    
    def f2():
        print('第一次f2')
        g1.switch()
        time.sleep(1)
        print('第二次f2')
    
    g1 = greenlet(f1)  #实例化一个greenlet对象,并将任务名称作为参数参进去
    g2 = greenlet(f2)
    g1.switch() #执行g1对象里面的任务

    gevent模块

    from gevent import monkey;monkey.patch_all()  

      这个模块只要有io的地方就会自动切换,不必非要用gevent模块,下面的代码中gevent.sleep(1) 换成time.sleep(1)也可以执行.

    import gevent
    from gevent import monkey;monkey.patch_all()
    import time
    import threading
    
    def f1():
        print('第一次f1')
        gevent.sleep(1)  # time.sleep(1)
        print('第二次f1')
    
    def f2():
        print('第一次f2')
        gevent.sleep(1)  #time.sleep(1)
        print('第二次f2')
    
    g1 = gevent.spawn(f1) #异步提交了f1任务
    g2 = gevent.spawn(f2) #异步提交了f2任务
    gevent.joinall([g1,g2])  #相当于g1.join()+g2.join()
    print('主程序任务')
  • 相关阅读:
    Boost练习程序(multi_index_container)
    mathematica练习程序(图像取反)
    【转】媒体播放器三大底层架构
    CentOS安装中文支持
    Retrofit2文件上传下载及其进度显示
    Andorid面试问题整理
    5分钟实现Android中更换头像功能
    Android中突发情况Activity数据的保存和恢复
    5分钟让你学会用最高效的工具解析所有Json
    android http 和https请求
  • 原文地址:https://www.cnblogs.com/fu-1111/p/10268945.html
Copyright © 2011-2022 走看看