zoukankan      html  css  js  c++  java
  • python3之threading模块(上)

    threading模块提供了管理多个线程执行的API。

    最简单的用法。就是用一个目标函数实例化一个Thread对象。start()开始工作,join()等待当前线程完成。

      1: import threading
    
      2: def work():
    
      3:     print("working")
    
      4: for i in range(5):
    
      5:     t = threading.Thread(target=work)
    
      6:     t.start()
    
      7:     print("please wait!")
    
      8:     t.join()

    结果

      1: working
    
      2: please wait!
    
      3: working
    
      4: please wait!
    
      5: working
    
      6: please wait!
    
      7: working
    
      8: please wait!
    
      9: working
    
     10: please wait!

    当然也可以传递参数。

      1: import threading
    
      2: def work(i):
    
      3:     print("%i is working" %i)
    
      4: for i in range(5):
    
      5:     t = threading.Thread(target=work,args=(i,))
    
      6:     t.start()
    
      7:     print("please wait!")
    
      8:     t.join()

    结果

      1: 0 is working
    
      2: please wait!
    
      3: 1 is working
    
      4: please wait!
    
      5: 2 is working
    
      6: please wait!
    
      7: 3 is working
    
      8: please wait!
    
      9: 4 is working
    
     10: please wait!

    确定当前线程

    每个Thread实例都有一个带有默认值的名字,也可以传入name参数更改。

      1: import threading
    
      2: import time
    
      3: def work():
    
      4:     print(threading.current_thread().getName(),"starting!")
    
      5:     time.sleep(0.5)
    
      6:     print(threading.current_thread().getName(),"end!")
    
      7: 
    
      8: t = threading.Thread(name="worker", target=work)
    
      9: t.start()
    
     10: print("please wait!")
    
     11: t.join()

    结果

      1: worker starting!
    
      2: please wait!
    
      3: worker end!

    出于线程安全的考虑,我们下面用logging模块输出消息。

    守护线程与非守护线程

    一般来说,程序都会等待所有线程完成工作之后才退出。而守护线程可以一直运行而不阻塞主程序的退出。传入daemon=True或者调用setDaemon()方法并提供参数True来构造守护线程。

      1: import threading
    
      2: import time
    
      3: import logging
    
      4: def daemon():
    
      5:     logging.debug("start")
    
      6:     time.sleep(0.5)
    
      7:     logging.debug("exite")
    
      8: def non_deamon():
    
      9:     logging.debug("start")
    
     10:     logging.debug("exit")
    
     11: logging.basicConfig(
    
     12:     level=logging.DEBUG,
    
     13:     format='(%(threadName)-10s) %(message)s',
    
     14: )
    
     15: d = threading.Thread(name='deamon', target=daemon, daemon=True)
    
     16: t = threading.Thread(name="non-deamon", target=non_deamon)
    
     17: d.start()
    
     18: t.start()

    结果中没有看到守护线程的退出的消息,主程序就已经退出了。

      1: (deamon    ) start
    
      2: (non-deamon) start
    
      3: (non-deamon) exit

    要等待一个守护线程结束,需要使用join()方法。默认下,join会无限阻塞,但可以传入浮点值。在时间内线程即使未完成,join也会强制返回。

      1: import threading
    
      2: import time
    
      3: import logging
    
      4: def daemon():
    
      5:     logging.debug("start")
    
      6:     time.sleep(0.5)
    
      7:     logging.debug("exite")
    
      8: def non_deamon():
    
      9:     logging.debug("start")
    
     10:     logging.debug("exit")
    
     11: logging.basicConfig(
    
     12:     level=logging.DEBUG,
    
     13:     format='(%(threadName)-10s) %(message)s',
    
     14: )
    
     15: d = threading.Thread(name='deamon', target=daemon, daemon=True)
    
     16: t = threading.Thread(name="non-deamon", target=non_deamon)
    
     17: d.start()
    
     18: d.join(0.2)
    
     19: t.start()

    结果还是没有看到守护线程的结束退出的消息。

      1: (deamon    ) start
    
      2: (non-deamon) start
    
      3: (non-deamon) exit

    枚举所有线程

    threading.enumerate()会返回一个Thread实例的一个列表。由于等待当前主程序终止会引入一种死锁的情况,所以跳过这个线程等待。注意根据电脑配置,合理调节线程睡眠时间,否则会由于缺少logging参数而报错。

      1: import threading
    
      2: import time
    
      3: import logging
    
      4: import random
    
      5: def worker():
    
      6:     pause = random.randint(1, 5) / 2
    
      7:     logging.debug("sleeping %0.2f" % pause)
    
      8:     time.sleep(pause)
    
      9:     logging.debug("end!")
    
     10: logging.basicConfig(
    
     11:     level=logging.DEBUG,
    
     12:     format='(%(threadName)-10s) %(message)s',
    
     13: )
    
     14: for i in range(3):
    
     15:     t = threading.Thread(target=worker, daemon=True)
    
     16:     t.start()
    
     17: # 拿到当前主线程
    
     18: main_thread = threading.main_thread()
    
     19: for t in threading.enumerate():
    
     20:     if t is main_thread:
    
     21:         continue
    
     22:     logging.debug("joining %s" % t.getName())
    
     23:     t.join()
    上述程序各个线程执行的顺序image

    输出顺序可能不一样,

      1: (Thread-1  ) sleeping 0.50
    
      2: (Thread-2  ) sleeping 1.50
    
      3: (Thread-3  ) sleeping 2.00
    
      4: (MainThread) joining Thread-1
    
      5: (Thread-1  ) end!
    
      6: (MainThread) joining Thread-2
    
      7: (Thread-2  ) end!
    
      8: (MainThread) joining Thread-3
    
      9: (Thread-3  ) end!
  • 相关阅读:
    Kalman Filters
    基于堆栈实现计算器
    Centos 7创建软连接,硬连接的方法
    Centos 7下对磁盘的分区格式化挂载交换空间的建立
    文件的归档打包压缩解压缩
    文件目录操作命令及权限的修改设置
    用户添加修改文件的操作
    linux今日学习命令 who
    CentOS安装流程
    计算机网络基础
  • 原文地址:https://www.cnblogs.com/haoqirui/p/10321194.html
Copyright © 2011-2022 走看看