线程
创建线程的基本步骤
- 创建函数
- 创建线程对象,并制定函数
- 开启线程
代码示例:
import threading
import time
def work1(): # 1.定义函数
for i in range(5):
print('正在扫地----', i)
time.sleep(1)
def main():
"""测试线程的基本使用"""
# 2.创建线程对象
t1 = threading.Thread(target=work1) # 注意点:传递给 target 的是函数名,不要写函数名后写小括号
# 3.开启线程。调用 start 的时候线程才会真正的开启
t1.start()
if __name__ == '__main__':
main()
注意点
- ==子线程代码执行结束就会被销毁==
- 主线程会等待所有的子线程都结束后才销毁
- ==主线程死亡会导致所有的子线程死亡==
- 开启线程。==调用 start 的时候线程才会真正的开启==
- 线程间争夺时间片是完全无序的
自定义线程类
基本步骤
- 定义一个类继承 Thread
- 类里面提供 run 方法
- 创建自定义线程类的对象
- 调用 start 开启线程,并自动执行 run 方法
代码示例
import time
import threading
class MyThread(threading.Thread): # 1. 定义一个类继承 Thread
def run(self): # 2. 类里面提供 run 方法
for i in range(5):
print('正在扫地---', self.name)
time.sleep(1)
def main():
"""测试自定义线程类"""
t1 = MyThread() # 3. 创建自定义线程类的对象
t1.start() # 4.调用 start 开启线程,并自动执行 run 方法
print(t1)
if __name__ == '__main__':
main()
注意点
- 自定义线程类只需要重写Thread类中的run方法即可。
线程之间共享数据
全局变量
多线程之间,使用全局变量传递参数和函数之间使用全局变量传递参数,用法一致
代码示例
import threading
import time
def work1():
global num
num = 100 # 线程1 修改全局变量
print('work1---num=', num)
def work2(): # 线程2 可以获取 线程1 修改的结果
print('work2----,num=', num)
num = 0
def main():
"""测试线程间使用全局变量共享数据"""
t1 = threading.Thread(target=work1)
t1.start()
time.sleep(0.5)
t2 = threading.Thread(target=work2)
t2.start()
if __name__ == '__main__':
main()
传参
import threading
import time
def work1(tmp): # 函数的参数要和线程的 args 元素一一对应
tmp.append(22)
print('work1---tmp=', tmp)
def work2(tmp): # 线程2 可以获取 线程1 修改的结果
print('work2----,tmp=', tmp)
def main():
"""测试线程间使用传参的方式共享数据"""
ls = [] # 线程间使用参数共享数据,必须使用可变类型的数据
t1 = threading.Thread(target=work1, args=(ls,)) # 给线程传参,使用 args 传递一个元组
t1.start()
time.sleep(0.5)
t2 = threading.Thread(target=work2, args=(ls,))
t2.start()
if __name__ == '__main__':
main()
注意点
- 线程间使用参数共享数据,必须使用可变类型的数据
- 给线程传参,使用 args 传递一个元组
- 参数必须和args中的元素一一对应
线程同步
线程同步指的是多线程之间互相协同,互相配合
互斥锁
互斥锁是实现线程同步的一种方案,多线程之间共享一把锁,这样在针对同一份数据操作的时候,可以有效的保证数据的安全
实现步骤:
# 创建锁
mutex = threading.Lock()
# 锁定
mutex.acquire()
# 释放
mutex.release()
其他
多线程实现按顺序执行
当需要按顺序测试线程的时候,可以在线程的启动间添加延时(一般用于测试)
代码示例
import threading
import time
def work1():
for i in range(200):
print('正在扫地~~', i)
open('04-TCP文件下载器-服务器优化.py').read() # 读取文件,产生一个变化的延迟时间
def work2():
for i in range(200):
print('正在搬砖~~', i)
open('04-TCP文件下载器-服务器优化.py').read() # 读取文件,产生一个变化的延迟时间
def main():
t1 = threading.Thread(target=work1)
t1.start()
time.sleep(3) # 当需要按顺序测试线程的时候,可以在线程的启动间添加延时
t2 = threading.Thread(target=work2)
t2.start()
if __name__ == '__main__':
main()
并行和并发
- 并行:cpu核心数比程序多,每个程序独占一个cpu核心数
- 并发:cpu核心数比程序少,多个程序共享一个cpu核心数