1.线程的概念
- 线程是进程中执行代码的一个分支,每个执行分支(线程)要想工作执行代码需要CPU进行调度,也就是说线程是CPU调度的基本单位,每个进程至少都有一个线程,而这个线程就是我们通常说的主线程。
- 线程是一个独立的执行流,系统中的多个线程可以并行及并发执行,多个线程可以共享数据与资源、利用了所谓的共享信息空间。
- 一个线程主要由3个元素构成: 程序计数器、寄存器、与栈
2.Python中多线程 ---- threading模块
1.导入线程模块import threading
2.线程类Thread参数说明
Thread(group,target,name,args,kwargs)
3.多线程的注意点
- gourp:线程组,目前只能使用None
- target:执行的目标任务名
- args:以元组的方式给执行任务传参
- kwargs:以字典方式给执行任务传参
- name:线程名,一般不用设置
- 当调用Thread的时候,不会创建线程
- 调用Thread创建出来的实例对象的start方法的时候,才会创建线程以及让这个线程开始运行线程真正创建是调用start(),线程真正结束是主线程结束
- 主线程会等待所有的子线程结束后才结束
- 线程创建后谁先执行是不确定的,要确定先后的顺序可以通过延时的方式来保证只要主线程一死,其他的子线程就会全部结束
3.多线程的使用
下面看例子:
- 首先看看不使用多线程,使用单线程所花费的时间
import time def eat_fish(): print("--正在吃鱼--") time.sleep(1) if __name__ == '__main__': for i in range(5): eat_fish() ''' 运行的结果, 一次只执行一次,5秒钟执行完成 --正在吃糖果-- --正在吃糖果-- --正在吃糖果-- --正在吃糖果-- --正在吃糖果-- '''
- 用threading创建多线程来执行任务
t = threading.Thread(target=函数名) # 生成一个子线程对象
t.start() # 然后利用这个对象调用start()方法,,来创建一个子线程
详解:
threading.Thread(
group=None,name=None,args=(),kwargs={}
)
# 导入线程模块 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秒执行完成 5个线程 --正在吃糖果-- --正在吃糖果-- --正在吃糖果-- --正在吃糖果-- --正在吃糖果-- '''
4.获取线程(查看线程的名称)
threading.current_thread()
5.查看线程数
threading.enumerate() # 返回值是一个列表,里面有当前执行的所有线程
- 循环查看当前运行的线程
Thread执行的函数结束时,线程就结束了,所以打印线程的长度是就会少一个。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时,线程是从什么时候开始创建的,什么时候结束
结果: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()
6. 通过继承Thread类完成创建线程
- 适合一个线程里面做的事情比较复杂,而且分了多个函数来做,一般来封装成一个类,类里面覆写run()方法用这个类的实例对象来调用start()方法
- 如果类里面还有其他的方法想要用子线程,直接在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'[email protected]
I'[email protected]
I'[email protected]