zoukankan      html  css  js  c++  java
  • day34 线程池 协程

    今日内容:

    1. 线程的其他方法

    2.线程队列(重点)

    3.线程池(重点)

    4.协程

    1.线程的其他方法

    语法:

    Threading.current_thread() # 当前正在运行的线程对象的一个列表

    GetName() # 获取线程名

    Ident() 获取线程的ID

    Threading.active_count() # 当前正在运行的线程数量

    import threading
    import time
    from threading import Thread,current_thread
    
    def f1():
        time.sleep(1)
        print('子进程的名称',current_thread().getName())  # Thread-1
        print(f'{i}号线程任务')
    
    if __name__=='__main__':
        t1=Thread(target=f1,args=(2,))
        t1.start()
        print('主线程名称',current_thread().getName())  # MainThread
        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()) #主线程和子线程的和 print('主线程结束')

    2.线程队列(重点)

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

    线程队列我们这里介绍3种:

    import queue

    1).先进先出队列  queue.Queue

    import queue
    q=queue.Queue(3)
    q.put(1)
    q.put(2)
    print(q.qsize())# 查看当前队列的长度
    q.put(3)
    try:
        q.put_nowait(4) # 和put效果一样,但是如果队列满了继续放它会报错
    except exception:
        print('队列满了,放不进去了')
    print(q.full()) # 查看当前队列是否是满的
    
    print(q.get())#1
    print(q.get())#2
    print(q.get())#3
    print(q.get_nowait()) #和get效果一样,但是如果队列空了继续拿会报错
    print(q.empty())# 查看当前队列是否是空的
    

    2).先进后出队列 queue.LifoQueue

    import queue
    
    q=queue.LifoQueue(3)
    q.put(1)
    q.put(2)
    print(q.qsize())
    q.put(3)
    q.put_nowait(4)
    print(q.full())
    
    print(q.get())#3
    print(q.get())#2
    print(q.get())#1
    print(q.empty()) #查看队列是否是空的
    print(q.get_nowait())
    

    3).优先级队列 queue.PriorrityQueue

    q=queue.priorityQueue(3)
    
    q.put((2,'alex')) # 必须是元组
    q.put((2,'大力')) #数据类型相同才能比较
    q.put((-2,'666'))
    
    # 如果值里面的元素是int类型,如果这两个值大小,就先拿比较小的那个;如果这两个值大小相同,
    那么比较的是下一个元素的第一个ascii码大小,小的优先被取出来 # 如果元素类型是字符串,那么依次比较每个字母的ascii的大小,小的被优先拿出来 # 字典不能比较 print(q.get()) print(q.get()) print(q.get())

    3.线程池

    from concurrent_futures import ThreadPoolExecutor,ProcessPoolExecutor

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

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

    p.map(f1,可迭代对象) # 异步执行

    res=p.submit(f1,无敌传参,传什么都行) #异步提交任务

    print(res.result()) #和get方法一样,如果没有结果,会等待,阻塞程序

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

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

    4.协程

    生成器版协程:(有BUG)

    import time
    def f1():
        for i in range(10):
            time.sleep(1)
            print('f1执行后的结果',i)
            yield
    
    def f2():
        g=f1()
        for i in range(10):
            time.sleep(1)
            print('f2执行后的结果',i)
            next(g)
    
    f1()
    f2()    
    

    greenlet 版协程

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

    gevent版真正的协程(真正意义上的协程,异步执行程序)

    import gevent
    from gevent import monkey;monkey.patch_all()
    import time 
    import threading
    
    def f1():
        print('第一次f1')
        gevent.sleep(1)
        print('第二次执行f1')
    
    def f2():
        print('第一次执行f2')
        gevent.sleep(1)
        print('第二次执行f2')
    
    g1=gevent.spawn(f1)
    g2=gevent.spawn(f2)
    gevent.joinall([g1,g2]) # 相当于g1.join()  g2.join()
    print('主程序任务结束')
    

      

  • 相关阅读:
    多个tab切换demo
    react添加和删除定时器的地方
    编写C语言的两种方法----Visual Studio/CodeBlocks
    C++学习笔记---引用的本质
    C++学习笔记---指针
    C++学习笔记---数据类型
    博客园皮肤SimpleMemory深色风格皮肤
    SQL DELETE语句如何让表使用别名的方法
    Asp.Net实现局部刷新,ScriptManager和UpdatePanel控件的使用
    由于可能不会将凭据发送到远程计算机,因此将不会进行连接。若要获得协助,请与您的系统管理员联系。(转)
  • 原文地址:https://www.cnblogs.com/zty1304368100/p/10268051.html
Copyright © 2011-2022 走看看