• python-day34(GIL锁,线程池)


    一. GIL锁

      GIL锁(Global Interpreter Lock),本质就是一把互斥锁

     

           >>>>>关于GIL锁<<<<<

    二. 线程队列

      queue队列:  使用import queue ,用法与进程Queue一样,队列都是安全的,不会出现多个线程

      抢占同一个资源或数据的情况. 

     1 import queue
     2 
     3 # # 先进先出
     4 q = queue.Queue(3)
     5 q.put(1)
     6 q.put(13)
     7 q.put(2)
     8 while 1:
     9     try:
    10         print(q.get_nowait())
    11     except:
    12         break
    13 '''
    14 结果:
    15 1
    16 13
    17 2
    18 '''
    先进先出
     1 import queue
     2 # 后进先出
     3 q = queue.LifoQueue(3)
     4 q.put((2,222))
     5 q.put((1,111))
     6 q.put((3,333))
     7 print(q.get())
     8 print(q.get())
     9 print(q.get())
    10 '''
    11 结果:
    12 (3, 333)
    13 (1, 111)
    14 (2, 222)
    15 '''
    先进后出
     1 import queue
     2 # 排序 ASCII 码排序
     3 q = queue.PriorityQueue(3)
     4 q.put(333)
     5 q.put(222)
     6 q.put(111)
     7 print(q.get())
     8 print(q.get())
     9 print(q.get())
    10 print(q.get())
    11 '''
    12 结果:
    13 111
    14 222
    15 333
    16 '''
    ASCII 编码排序

    三. 线程池

      concurrent.futures模块  使用threadPoolExecutor 和ProcessPoolExecutor的方式一样,

    concurrent.futures模块提供了高度封装的异步调用接口
    ThreadPoolExecutor:线程池,提供异步调用
    ProcessPoolExecutor: 进程池,提供异步调用
    Both implement the same interface, which is defined by the abstract Executor class.
    
    #2 基本方法
    #submit(fn, *args, **kwargs)
    异步提交任务
    
    #map(func, *iterables, timeout=None, chunksize=1) 
    取代for循环submit的操作
    
    #shutdown(wait=True) 
    相当于进程池的pool.close()+pool.join()操作
    wait=True,等待池内所有任务执行完毕回收完资源后才继续
    wait=False,立即返回,并不会等待池内的任务执行完毕
    但不管wait参数为何值,整个程序都会等到所有任务执行完毕
    submit和map必须在shutdown之前
    
    #result(timeout=None)
    取得结果
    
    #add_done_callback(fn)
    回调函数
     1 import time
     2 import os
     3 import threading
     4 from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
     5 
     6 def func(n):
     7     time.sleep(2)
     8     print('%s打印的:'%(threading.get_ident()),n)
     9     return n*n
    10 tpool = ThreadPoolExecutor(max_workers=5) #默认一般起线程的数据不超过CPU个数*5
    11 # tpool = ProcessPoolExecutor(max_workers=5) #进程池的使用只需要将上面的ThreadPoolExecutor改为ProcessPoolExecutor就行了,其他都不用改
    12 #异步执行
    13 t_lst = []
    14 for i in range(5):
    15     t = tpool.submit(func,i) #提交执行函数,返回一个结果对象,i作为任务函数的参数 def submit(self, fn, *args, **kwargs):  可以传任意形式的参数
    16     t_lst.append(t)  #
    17     # print(t.result())
    18     #这个返回的结果对象t,不能直接去拿结果,不然又变成串行了,可以理解为拿到一个号码,等所有线程的结果都出来之后,我们再去通过结果对象t获取结果
    19 tpool.shutdown() #起到原来的close阻止新任务进来 + join的作用,等待所有的线程执行完毕
    20 print('主线程')
    21 for ti in t_lst:
    22     print('>>>>',ti.result())
    23 
    24 # 我们还可以不用shutdown(),用下面这种方式
    25 # while 1:
    26 #     for n,ti in enumerate(t_lst):
    27 #         print('>>>>', ti.result(),n)
    28 #     time.sleep(2) #每个两秒去去一次结果,哪个有结果了,就可以取出哪一个,想表达的意思就是说不用等到所有的结果都出来再去取,可以轮询着去取结果,因为你的任务需要执行的时间很长,那么你需要等很久才能拿到结果,通过这样的方式可以将快速出来的结果先拿出来。如果有的结果对象里面还没有执行结果,那么你什么也取不到,这一点要注意,不是空的,是什么也取不到,那怎么判断我已经取出了哪一个的结果,可以通过枚举enumerate来搞,记录你是哪一个位置的结果对象的结果已经被取过了,取过的就不再取了
    29 
    30 #结果分析: 打印的结果是没有顺序的,因为到了func函数中的sleep的时候线程会切换,谁先打印就没准儿了,但是最后的我们通过结果对象取结果的时候拿到的是有序的,因为我们主线程进行for循环的时候,我们是按顺序将结果对象添加到列表中的。
    31 # 37220打印的: 0
    32 # 32292打印的: 4
    33 # 33444打印的: 1
    34 # 30068打印的: 2
    35 # 29884打印的: 3
    36 # 主线程
    37 # >>>> 0
    38 # >>>> 1
    39 # >>>> 4
    40 # >>>> 9
    41 # >>>> 16
    ThreadPoolExecutor的简单使用

      ProcessPoolExecutor的使用:

    只需要将这一行代码改为下面这一行就可以了,其他的代码都不用变
    tpool = ThreadPoolExecutor(max_workers=5) #默认一般起线程的数据不超过CPU个数*5
    # tpool = ProcessPoolExecutor(max_workers=5)
    
    你就会发现为什么将线程池和进程池都放到这一个模块里面了,用法一样

      map的使用

     1 import time
     2 from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
     3 from multiprocessing import Pool
     4 
     5 def fun(n):
     6     time.sleep(1)
     7     print(n)
     8     return n**2
     9 if __name__ == '__main__':
    10     t_p = ThreadPoolExecutor(4)
    11     # t_p = ProcessPoolExecutor(4)
    12     p_pool = Pool(4)
    13     res_lst = []
    14 
    15     # res = t_p.map(fun ,range(10))
    16     #
    17     # print(res)
    18     # t_p.shutdown()
    19     # print('主线程结束')
    20     # for i in res:
    21     #     print(i)
    22 # ------------------------------------/
    23 #     for i in range(10):
    24 #         res = t_p.submit(fun,i)
    25 #         res_lst.append(res)
    26 #     t_p.shutdown()
    27 # 
    28 #     for i in res_lst:
    29 #         print(i.result())
    30 # ---------------------------------------
    31     # for i in range(10):
    32     #     res = p_pool.apply_async(fun,(i,))
    33     #     res_lst.append(res)
    34     #     print(res.get())
    35     # p_pool.close()
    36     # p_pool.join()
    37     # for i in res_lst:
    38     #     print(i.get())
    map的使用

    四. 线程池的回调函数

     1 import time
     2 from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
     3 from multiprocessing import Pool
     4 
     5 def fun(n):
     6     time.sleep(1)
     7     return n*n
     8 def call_bcak(m):
     9     print('结果为: %s' %m.result())
    10 
    11 def c_back(m):
    12     print('结果为: %s' %m)
    13 if __name__ == '__main__':
    14     p = Pool(4)
    15 
    16     # t_p = ThreadPoolExecutor(4)
    17     # lst = []
    18     # for i in range(10):
    19     #     res = t_p.submit(fun,i)
    20     #     lst.append(res)
    21     # t_p.shutdown()
    22     # for i in lst:
    23     #     i.add_done_callback(call_bcak)
    24 # -----------------------------------------------------
    25 #     lst = []
    26 #     for i in range(10):
    27 #         res = p.apply_async(fun,args=(i,),callback=c_back)
    28 #         # print(res.get())
    29 #     p.close()
    30 #     p.join()
    回调函数

     >>>>>>>>>更多点击

  • 相关阅读:
    java积累
    J2SE J2EE J2ME的区别
    php无刷新上传图片
    C++小例子
    交通银行万事达Y-POWER信用卡 普卡
    代码面试最常用的5大算法
    php 读取 word
    PHP Simple HTML DOM 使用
    curl http认证
    PHP PDO 安装使用
  • 原文地址:https://www.cnblogs.com/Thui/p/10059496.html
Copyright © 2020-2023  润新知