Python中threading模块
可以总结出:
(1)当调用Thread的时候,不会创建线程
(2)调用Thread创建出来的实例对象的start方法的时候,才会创建线程以及让这个线程开始运行
线程真正创建是调用start(),线程真正结束是主线程结束
(3)主线程会等待所有的子线程结束后才结束
(4)线程创建后谁先执行是不确定的,要确定先后的顺序可以通过延时的方式来保证
(5)只要主线程一死,其他的子线程就会全部结束
下面看例子:
1. 用threading创建多线程来执行任务
单线程执行
import time
def eat_fish():
print("--正在吃鱼--")
time.sleep(1)
if __name__ == '__main__':
for i in range(5):
eat_fish()
'''
运行的结果, 一次只执行一次,5秒钟执行完成
--正在吃糖果--
--正在吃糖果--
--正在吃糖果--
--正在吃糖果--
--正在吃糖果--
'''
多线程执行
t = threading.Thread(target=函数名) # 生成一个子线程对象
t.start() # 然后利用这个对象调用start()方法,,来创建一个子线程
import threading
import time
def eat_candy():
print("--正在吃糖果--")
time.sleep(1)
if __name__ == '__main__':
for i in range(5):
t = threading.Thread(target=eat_candy) # 给target传入函数的名字
# 生成一个实例对象 t
t.start() # 启动线程,即让线程开始执行
'''
运行的结果, 一次就执行完成,花费1秒执行完成
--正在吃糖果--
--正在吃糖果--
--正在吃糖果--
--正在吃糖果--
--正在吃糖果--
'''
2. 查看线程数
threading.enumerate() # 返回值是一个列表,里面有当前执行的所有线程
(1) 循环查看当前运行的线程
import threading
import time
def test1():
for i in range(3):
print("----test1---%d---"%i)
time.sleep(1)
'''如果创建Thread时执行的函数,运行结束那么意味着 这个子线程就结束了'''
def test2():
for i in range(6):
print("----test2---%d---"%i)
time.sleep(1)
def main():
t1 = threading.Thread(target=test1)
t2 = threading.Thread(target=test2)
t1.start()
t2.start()
while True:
print(threading.enumerate()) # 打印出线程的列表
'''所有的线程只剩一个的时候(即主线程)就退出'''
if len(threading.enumerate())<=1:
break
time.sleep(1)
if __name__ == '__main__':
main()
Thread执行的函数结束时,线程就结束了,所以打印线程的长度是就会少一个。
(2) 在使用Thread时,线程是从什么时候开始创建的,什么时候结束
import threading
import time
def test1():
for i in range(5):
print("----test1---%d---" % i)
time.sleep(1)
def main():
# 在调用Thread之前先打印当前线程信息
print(threading.enumerate())
t1 = threading.Thread(target=test1)
# 在调用Thread之后打印
print(threading.enumerate())
t1.start()
# 在调用start()之后打印
print(threading.enumerate())
if __name__ == '__main__':
main()
结果:
3. 通过继承Thread类完成创建线程
(1) 适合一个线程里面做的事情比较复杂,而且分了多个函数来做,一般来封装成一个类,
类里面覆写run()方法
用这个类的实例对象来调用start()方法
(2)如果类里面还有其他的方法想要用子线程,
直接在run()方法里面调用就行(例如:self.login())
如果直接用实例.方法名时,不会创建子线程
import threading
import time
class MyThread(threading.Thread):
def run(self):
for i in range(3):
time.sleep(1)
msg = "I'm"+self.name+"@"+str(i) # name 属性中保存的是当前线程的名字
print(msg)
def login(self):
pass
'''
如果类里面还有其他的方法想要用子线程,
直接在run()方法里面调用就行(例如:self.login())
如果直接用实例.方法名时,不会创建子线程,
'''
if __name__ == '__main__':
t = MyThread()
t.start() # 直接利用类的实例对象调用start()方法
运行结果:
I'mThread-1@0
I'mThread-1@1
I'mThread-1@2