详解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异步任务队列示例
Apr 01 Python
python删除特定文件的方法
Jul 30 Python
python开发之str.format()用法实例分析
Feb 22 Python
Windows下的Python 3.6.1的下载与安装图文详解(适合32位和64位)
Feb 21 Python
Python实现求两个数组交集的方法示例
Feb 23 Python
基于django ManyToMany 使用的注意事项详解
Aug 09 Python
Django中FilePathField字段的用法
May 21 Python
详解如何在pyqt中通过OpenCV实现对窗口的透视变换
Sep 20 Python
详解如何修改python中字典的键和值
Sep 29 Python
matplotlib 画动态图以及plt.ion()和plt.ioff()的使用详解
Jan 05 Python
python源码剖析之PyObject详解
May 18 Python
LyScript实现绕过反调试保护的示例详解
Aug 14 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
用PHP+MySql编写聊天室
2006/10/09 PHP
php阻止页面后退的方法分享
2014/02/17 PHP
thinkPHP查询方式小结
2016/01/09 PHP
php 在字符串指定位置插入新字符的简单实现
2016/06/28 PHP
PHP多维数组排序array详解
2017/11/21 PHP
PHP检测接口Traversable用法详解
2017/12/29 PHP
PHP发送邮件确认验证注册功能示例【修改别人邮件类】
2019/11/09 PHP
jquery中通过父级查找进行定位示例
2013/06/28 Javascript
js使下拉列表框可编辑不止是选择
2013/12/12 Javascript
IE6-IE9中tbody的innerHTML不能赋值的解决方法
2014/06/05 Javascript
JS去除空格和换行的正则表达式(推荐)
2016/06/14 Javascript
通过bootstrap全面学习less
2016/11/09 Javascript
bootstrap时间插件daterangepicker使用详解
2017/10/19 Javascript
vue中使用vue-router切换页面时滚动条自动滚动到顶部的方法
2017/11/28 Javascript
react组件基本用法示例小结
2020/04/27 Javascript
vue页面引入three.js实现3d动画场景操作
2020/08/10 Javascript
vant中的toast层级改变操作
2020/11/04 Javascript
Python魔术方法详解
2015/02/14 Python
python自然语言编码转换模块codecs介绍
2015/04/08 Python
简单谈谈python中的多进程
2016/11/06 Python
django 在原有表格添加或删除字段的实例
2018/05/27 Python
Python Flask前后端Ajax交互的方法示例
2018/07/31 Python
python银行系统实现源码
2019/10/25 Python
python生成器/yield协程/gevent写简单的图片下载器功能示例
2019/10/28 Python
python opencv根据颜色进行目标检测的方法示例
2020/01/15 Python
基于python判断字符串括号是否闭合{}[]()
2020/09/21 Python
python logging模块的使用详解
2020/10/23 Python
运动鞋、足球鞋和慕尼黑球衣:Sport Münzinger
2019/08/26 全球购物
天游软件面试
2013/11/23 面试题
销售内勤岗位职责
2014/04/15 职场文书
我的中国梦演讲稿初中篇
2014/08/19 职场文书
绿色校园广播稿
2014/10/13 职场文书
2014年党员个人工作总结
2014/12/02 职场文书
申报材料格式
2014/12/30 职场文书
导游词幽默开场白
2019/06/26 职场文书
apache基于端口创建虚拟主机的示例
2021/04/22 Servers