详解python中的线程


Posted in Python onFebruary 10, 2018

Python中创建线程有两种方式:函数或者用类来创建线程对象。

函数式:调用 _thread 模块中的start_new_thread()函数来产生新线程。

类:创建threading.Thread的子类来包装一个线程对象。

1.线程的创建

1.1 通过thread类直接创建   

import threading
  import time
  def foo(n):
    time.sleep(n)
    print("foo func:",n)
  def bar(n):
    time.sleep(n)
    print("bar func:",n)
  s1=time.time()
  #创建一个线程实例t1,foo为这个线程要运行的函数
  t1=threading.Thread(target=foo,args=(3,))
  t1.start()  #启动线程t1
  #创建一个线程实例t2,bar为这个线程要运行的函数
  t2=threading.Thread(target=bar,args=(5,))
  t2.start()  #启动线程t2
  print("ending")
  s2=time.time()
  print("cost time:",s2-s1)

在这段程序里,一个函数会先休眠几秒钟,然后再打印一句话,第二个函数也是先休眠几秒钟,然后打印一句话。

接着程序会实例化两个线程,并调用两个函数来执行,最后会打印程序问总共执行了多少时间

程序运行结果如下:

ending
cost time: 0.002000093460083008
foo func: 3
bar func: 5

程序会先运行父线程,打印"ending",然后打印程序执行父线程的时间,最后才会运行子线程

1.2 通过thread类来继承式创建

import threading
  import time
  # 定义MyThread类,其继承自threading.Thread这个父类
  class MyThread(threading.Thread): 
    def __init__(self):
      threading.Thread.__init__(self)
    def run(self):
      print("ok")
      time.sleep(2)
      print("end t1")
  # 对类进行实例化
  t1=MyThread()  
  # 启动线程
  t1.start()
  print("ending")

2. Thread类的一些常用方法

2.1 join():在子线程完成之前,主线程将一直被阻塞****

线程的join方法必须在子线程的start方法之后定义
在第一个例子中加入两行代码,如下:   

import threading
  import time
  def foo(n):
    time.sleep(n)
    print("foo func:",n)
  def bar(n):
    time.sleep(n)
    print("bar func:",n)
  s1=time.time()
  t1=threading.Thread(target=foo,args=(3,))
  t1.start()
  t2=threading.Thread(target=bar,args=(5,))
  t2.start()
  t1.join()    # 阻塞t1线程
  t2.join()    # 阻塞t2线程
  print("ending")
  s2=time.time()
  print("cost time:",s2-s1)

再次执行程序,运行结果如下:

foo func: 3
bar func: 5
ending
cost time: 5.002285957336426

程序运行到子线程t1中的foo方法时会睡眠3秒钟,与此同时,子线程t2也在睡眠

等到子线程t1睡眠完成后,开始打印foo函数中的print语句,然后子线程t1执行完成

2秒钟之后,子线程t2睡眠完成,开始打印bar函数中的print语句,然后子线程t2也执行完成。

而在这之前,主线程一直处于阻塞状态。等到子线程执行完成之后主线程才会执行

2.2 setDeamon(True)

setDaemon方法作用是将进程声明为守护线程,必须在`start()`方法调用之前,
如果不设置为守护线程,程序会被无限挂起

在程序执行过程中,执行一个主线程,主线程又创建一个子线程时,主线程和子线程会分别运行。

当主线程运行完成时,会检验子线程是否执行完成,如果子线程执行完成,则主线程会等待子线程完成后再退出。

但是有的时候只要主线程执行完成之后,不管子线程是否执行完成,都和主线程一起退出,这个就需要调用setDeamon方法了。

拿第一个例子来说吧,现在我想让子线程t1和t2随同主线程关闭,代码如下:

import threading
  import time
  def foo(n):
    print("foo start")
    time.sleep(n)
    print("foo end...")
  def bar(n):
    print("bar start")
    time.sleep(n)
    print("bar end...")
  s1 = time.time()
  t1 = threading.Thread(target=foo, args=(3,))
  t1.setDaemon(True)
  t1.start()
  t2 = threading.Thread(target=bar, args=(5,))
  t2.setDaemon(True)
  t2.start()
  print("ending")
  s2 = time.time()
  print("cost time:", s2 - s1)

程序运行结果如下 :

foo start
bar start
ending
cost time: 0.003000020980834961

可以看到,把t1和t2都声明为守护线程后,程序自上而下执行,先执行子线程t1中的foo方法,打印foo函数中的第一条打印语句,然后子线程t1进入到睡眠状态。

然后子线程t2执行,打印bar函数中的第一条print语句,然后子线程t2进入睡眠状态,程序切换到主线程运行

主线程打印完"ending"语句,发现子线程t1和t2已经被设置为守护线程,所以主线程不需要再等待两个子线程执行完成,而是立即结束,打印整个程序的执行时间。

整个程序就跟随主线程一起关闭了。

2.3 子线程的一些其他方法

isAlive()      #判断一个线程是否是活动线程
getName()      #返回线程的名字
setName()      #设置线程的名字
  import threading
  import time
  def foo(n):
    time.sleep(n)
    print("foo func:", n)
  def bar(n):
    time.sleep(n)
    print("bar func:", n)
  s1 = time.time()
  t1 = threading.Thread(target=foo, args=(3,))
  t1.setDaemon(True)
  print("线程还未启动时,判断t1是否是活动的线程:", t1.isAlive()) # 线程还未启动,所以是False
  t1.start() # 启动线程
  print("线程已启动时,判断t1是否是活动的线程:", t1.isAlive()) # 线程已启动,所以是True
  print("修改前的线程名为:",t1.getName()) # 获取线程名
  t1.setName("t1")    #设置线程名
  print("修改后的线程名为:",t1.getName()) # 获取线程名
  t1.join()
  print("线程执行完成时,判断t1是不否是活动的线程:", t1.isAlive()) # 线程已执行完成,所以是False
  # print(threading.activeCount())
  print("ending")
  s2 = time.time()
  print("cost time:", s2 - s1)

程序执行结果:

线程还未启动时,判断t1是否是活动的线程: False
线程已启动时,判断t1是否是活动的线程: True
修改前的线程名为: Thread-1
修改后的线程名为: t1
foo func: 3
线程执行完成时,判断t1是不否是活动的线程: False
ending
cost time: 3.001171588897705

3.threading模块提供的一些方法

threading.currentThread()  #返回当前的线程变量
threading.enumerate()    #返回一个包含正在运行的线程的列表,不包括启动前和终止后的线程
threading.activeCount()   #返回正在运行的线程数量,等同于len(threading.enumerate())
  import threading
  import time
  def foo(n):
    time.sleep(n)
    print("foo func:", n)
  def bar(n):
    time.sleep(n)
    print("bar func:", n)
  s1 = time.time()
  t1 = threading.Thread(target=foo, args=(3,))
  t1.setDaemon(True)
  t1.start()
  t2 = threading.Thread(target=bar, args=(5,))
  t2.setDaemon(True)
  t2.start()
  print("程序中正在运行的线程数量:",threading.activeCount())
  print("程序中当前的线程变量:",threading.currentThread())
  print("当前正在运行的线程的列表:",threading.enumerate())
  print("ending")
  s2 = time.time()
  print("cost time:", s2 - s1)

程序执行结果:

程序中正在运行的线程数量: 3
程序中当前的线程变量: <_MainThread(MainThread, started 7064)>
当前正在运行的线程的列表: [<_MainThread(MainThread, started 7064)>, <Thread(Thread-1, started daemon 6384)>, <Thread(Thread-2, started daemon 2640)>]
ending
cost time: 0.002000093460083008

总结

以上所述是小编给大家介绍的详解python中的线程,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
详细讲解用Python发送SMTP邮件的教程
Apr 29 Python
Python脚本暴力破解栅栏密码
Oct 19 Python
Windows上配置Emacs来开发Python及用Python扩展Emacs
Nov 20 Python
Python中在脚本中引用其他文件函数的实现方法
Jun 23 Python
在centos7中分布式部署pyspider
May 03 Python
读取本地json文件,解析json(实例讲解)
Dec 06 Python
python getpass实现密文实例详解
Sep 24 Python
解决pytorch DataLoader num_workers出现的问题
Jan 14 Python
Python2 与Python3的版本区别实例分析
Mar 30 Python
python学习将数据写入文件并保存方法
Jun 07 Python
Python+logging输出到屏幕将log日志写入文件
Nov 11 Python
python 制作本地应用搜索工具
Feb 27 Python
Odoo中如何生成唯一不重复的序列号详解
Feb 10 #Python
python TCP Socket的粘包和分包的处理详解
Feb 09 #Python
python实现Adapter模式实例代码
Feb 09 #Python
python实现Decorator模式实例代码
Feb 09 #Python
Python多线程扫描端口代码示例
Feb 09 #Python
Python编程实现从字典中提取子集的方法分析
Feb 09 #Python
python tensorflow学习之识别单张图片的实现的示例
Feb 09 #Python
You might like
给海燕B411配件机起死回生配上件
2021/03/02 无线电
利用curl 多线程 模拟 并发的详解
2013/06/14 PHP
WordPress中查询文章的循环Loop结构及用法分析
2015/12/17 PHP
laravel 5.3 单用户登录简单实现方法
2019/10/14 PHP
Javascript实例教程(19) 使用HoTMetal(7)
2006/12/23 Javascript
jQuery之ajax删除详解
2014/02/27 Javascript
使用js操作css实现js改变背景图片示例
2014/03/10 Javascript
javascript的switch用法注意事项分析
2015/02/02 Javascript
jQuery实现手机号码输入提示功能实例
2015/04/30 Javascript
jstree创建无限分级树的方法【基于ajax动态创建子节点】
2016/10/25 Javascript
微信小程序新手教程之启动页的重要性
2019/03/03 Javascript
js实现固定区域内的不重叠随机圆
2019/10/24 Javascript
JavaScript中while循环的基础使用教程
2020/08/11 Javascript
微信小程序实现简单的select下拉框
2020/11/23 Javascript
[03:42]2014DOTA2国际邀请赛 第三日比赛排位扑朔迷离
2014/07/12 DOTA
Python实现简单的可逆加密程序实例
2015/03/05 Python
python实现爬虫统计学校BBS男女比例(一)
2015/12/31 Python
Python机器学习之SVM支持向量机
2017/12/27 Python
Python基于列表模拟堆栈和队列功能示例
2018/01/05 Python
如何安装多版本python python2和python3共存以及pip共存
2018/09/18 Python
python判断输入日期为第几天的实例
2018/11/13 Python
Python将视频或者动态图gif逐帧保存为图片的方法
2019/09/10 Python
Python实现图片识别加翻译功能
2019/12/26 Python
多个python文件调用logging模块报错误
2020/02/12 Python
python实现滑雪者小游戏
2020/02/22 Python
如何使用Cython对python代码进行加密
2020/07/08 Python
Python基于argparse与ConfigParser库进行入参解析与ini parser
2021/02/02 Python
HTML5移动端开发遇见的东西
2019/10/11 HTML / CSS
匡威意大利官方商店 :Converse意大利
2018/11/27 全球购物
综治工作心得体会
2014/09/11 职场文书
教师考核表个人总结
2015/02/12 职场文书
2015年七一建党节活动总结
2015/03/20 职场文书
2015年艾滋病宣传活动总结
2015/03/27 职场文书
迎新年主持词
2015/07/06 职场文书
python Tkinter模块使用方法详解
2022/04/07 Python
HTML中实现音乐或视频自动播放案例详解
2022/05/30 HTML / CSS