美文网首页
Threading多线程

Threading多线程

作者: 冬至是条狗 | 来源:发表于2018-12-13 11:49 被阅读0次

Python的线程受限制于GIL锁,所以在处理大量运算时不占优势。Cpython解释器的原因。但是日常所用多数属于IO密集型程序,开销要比进程小的多,而且速度快。

Threading模块中除了常用的Thread类还有一些方法:

  • threading.current_thread()方法:用来表明线程名的方法
  • threading.get_ident() 方法:用来获取线程ID的方法
  • threading.active_count()方法: 用来获取当前活跃的线程数量
  • threading.enumerate() 方法:将线程名字和ID用列表的方式显示出来

关于守护线程

  • 守护进程会随主进程结束而结束,防止出现僵尸进程。而守护线程则不会随着主线程结束而结束,进程会保留资源留给线程。

线程锁

  • 同进程锁一样,线程中同样有数据安全问题,为了不让多个线程对一个数据进行操作,使用线程锁可以保证数据安全。

  • 死锁的问题同样存在,使用递归锁RLock()可以解决死锁问题。在多个锁,锁一个数据时,互斥锁Lock()会产生死锁,而RLock()会保证在多个锁有一个在使用时,即使另外一个释放了,其他线程也不会获得锁。

  • 因为线程之间数据共享,所以使用公共数据时应该加锁。

信号量

  • 同一时间只有N个线程可以访问同一个短代码、数据

    import threading
    import time
    
    def func(sem, a, b):
        sem.acquire()
        time.sleep(1)
        print(a+b)
        sem.release()
    
    sem = threading.Semaphore(4)
    
    for i in range(10):
        t = threading.Thread(target=func, args=(sem, i, i+5))
        t.start()
    

事件

  • 事件在创建时,自身带有False状态,默认wait()堵塞,clear()设置堵塞,set()清除堵塞。线程的Condition模块中,有acquire()、wait()、release()、notify(int x) 几个方法,wait会等待notify中传入的数字进行执行。wait()在线程函数内部,而notify在外部传入数值,两段代码必须分别用acquire和release包围。

定时器Timer()

  • 利用定时器可以定时开启一个线程任务。

    def func():
        print("执行定时函数")
    
    
    threading.Timer(5.4, func).start()
    
  • 如果想循环调用一个定是函数,将调用的线程加入到执行函数中即可

    def func():
        print("执行定时函数")
        threading.Timer(5.4, func).start()
    
    threading.Timer(5.4, func).start()
    

队列 queue

  • 线程中使用的数据都可以共享,当出现数据安全问题时,为了保证线程数据安全,线程中也可以使用队列,这个队列并不在threading模块中,直接导入queue即可:

    import queue
    
    q = queue.Queue()
    q.put()
    q.put_nowait() # 会报错,需要加入异常处理
    q.get()
    q.get_nowait() # 会报错,需要加入异常处理
    
  • queue.LifoQueue() #栈,先进后出

  • queue.PriorityQueue() # 优先级队列

    q = queue.PriorityQueue()
    q.put((20, "a"))
    q.put((10, "b"))
    
    print(q.get())
    # 当优先级一样时,会根据数据的Ascii码排列先出顺序
    

线程池

使用python中新模块,concurrent中的线程池,同样也有进程池

import time
from concurrent.futures import ThreadPoolExecutor


def func(n):
    time.sleep(2)
    print(n)


tpool = ThreadPoolExecutor(max_workers=5)
for i in range(20):
    tpool.submit(func, i)
  • shutdown() 可以实现 join 和 close 效果

  • result() 可以取得返回的结果

    import time
    from concurrent.futures import ThreadPoolExecutor
    
    
    def func(n):
        time.sleep(2)
        print(n)
        return n*n
    
    
    tpool = ThreadPoolExecutor(max_workers=5)
    t_list = []
    for i in range(20):
        t = tpool.submit(func, i)  # 取结果
        t_list.append(t)
    tpool.shutdown()  # 等待所有线程执行完,并回收资源后继续执行主线程
    print("主进程")
    
    for t in t_list:
        print(t.result())  # 打印结果,使用result()取出结果
    
  • 在取得结果时,可以不用等待全部线程执行完,利用主线程取得结果即可。

回调函数

  • 当线程有返回值时,可以利用回调函数进行再次处理:
    import time
    from concurrent.futures import ThreadPoolExecutor
  def func(n):
      time.sleep(2)
      print(n)
      return n*n


  def call_back(n):
      print("执行的结果是:", n.result())  # 这里传入的时一个对象,需要进行result


  tpool = ThreadPoolExecutor(max_workers=5)

  for i in range(20):
      tpool.submit(func, i).add_done_callback(call_back)

  # tpool.shutdown()  # 等待所有线程执行完,并回收资源后继续执行主线程
  print("主进程")

相关文章

  • python多线程

    1.通过threading模块使用多线程 python中多线程的方式是引用threading模块 2.Thread...

  • C# Timer 最简单形象的教程

    System.Threading.Timer System.Threading.Timer是使用多线程时间定时类:...

  • 线程

    多线程--threading python的thread模块是比较底层的模块,python的threading模块...

  • threading

    关于threading模块的多线程的一些实验. threading.Thread 先来看一个最简单的实验多线程的方...

  • 06.系统编程-2.线程

    1、多线程-threading python的thread模块是比较底层的模块,python的threading模...

  • 1.6.1 Python线程使用 -- threading

    多线程-threading python的thread模块是比较底层的模块,python的threading模块是...

  • 线程实战

    多线程-threading python的thread模块是比较底层的模块,python的threading模块是...

  • 多线程

    threading 模块 在 Python 中实现多线程,可以利用 threading 模块中的 Thread 来...

  • Python Threading.Timer 多线程无法退出

    Python Threading.Timer 多线程无法退出

  • 线程 threading

    1. 多线程-threading python的thread模块是比较底层的模块,python的threading...

网友评论

      本文标题:Threading多线程

      本文链接:https://www.haomeiwen.com/subject/suaphqtx.html