多种任务同时进行
2、多任务的执行方式1.并发:多个任务在同一时间段内串行交替执行。
2.并行:多个任务在同一时刻内相互独立且同时执行。
Pass:说道线程,必须要首先介绍一下进程是什么?
进程:
- 运行的程序或软件,它是 *** 作系统进行资源分配的基本单位;比如我们运行的.py文件就是一个进程;
- 一个进程默认有一个线程,进程里可以创建多个线程,线程是依附在进程里的,没有进程就没有线程。
是进程中执行代码的一个分支,每个执行分支要想工作执行代码,需要cpu进行调度,也就是说线程是cpu调度的基本单位。
用下面的图帮助我们去了解进程与线程之间的关系:
2、创建单线程例1:
import time
def question():
print('夏天到了')
time.sleep(1)
print('大家都开空调了吗?')
def answer():
print('哈哈')
time.sleep(2)
print('那是当然的了!')
if __name__ =='__main__': # python模拟的程序入口,表示直接运行时,执行里面的代码
question()
answer()
**结果**:
夏天到了
(中间停留1s)
大家都开空调了吗?
哈哈
(中间停留2s)
那是当然的了!
例2:
import time
def dance(name):
print(f'{name}在跳See ya')
time.sleep(4)
if __name__=='__main__':
for i in range(2):
dance('任嘉伦')#调用dance函数,并且name=任嘉伦
**结果**:
任嘉伦在跳See ya
(中间停留4s)
任嘉伦在跳See ya
3、创建多线程
1.步骤:
- 1.导入模块 threading
- 2.创建子线程 Thread类
- 3.可设置守护线程 setDaemon() 主线程执行完了,子线程也会跟着结束
- 4.启动子线程 start()
- 5.可设置阻塞主线程 join() 阻塞主线程,等待子线程执行完
例1:多进程
import threading#导入进程方式1
import time
def dance(name):
print(f'{name}在跳See ya')
time.sleep(1)
if __name__ == '__main__':
for i in range(2):
# 创建线程
t = threading.Thread(target=dance,args=('任嘉伦',))
#启动线程
t.start()
结果:
任嘉伦在跳See ya
(中间间隔非常短)
任嘉伦在跳See ya
例2:多线程进阶,添加守护线程
import time
from threading import Thread#导入线程方式2
def f1():
print('任嘉伦')
time.sleep(1)
print('任嘉伦是我的偶像')
def f2():
print('好好学习')
time.sleep(1)
print('你就能见他了!')
if __name__=='__main__':
# 创建线程
f1 = Thread(target=f1)
f2 = Thread(target=f2)
# 设置守护线程
f1.setDaemon(True)
f2.setDaemon(True)
# 启动线程
f1.start()
f2.start()
print('哈哈!')
结果:
任嘉伦
(f1中的“任嘉伦是我的偶像”还没执行,主线程就先执行完了)
好好学习
(f2中的“你就能见他了!”还没有执行,主线程就先执行完了)
哈哈!
例3:多线程进阶,添加阻塞主线程,不添加守护线程
import time
from threading import Thread
def f1():
print('任嘉伦')
time.sleep(0.1)
print('任嘉伦是我的偶像')
def f2():
print('好好学习')
time.sleep(2)
print('你就能见他了!')
if __name__ == '__main__':
# 创建线程
f1 = Thread(target=f1)
f2 = Thread(target=f2)
# 启动线程
f1.start()
f2.start()
# 阻塞主线程----"我(主线程)等你(子线程)"
f1.join()
f2.join()
print('哈哈!')
# 结果:
# 任嘉伦
# 好好学习
# 任嘉伦是我的偶像
# 你就能见他了!
# 哈哈!
例4:多线程进阶,添加阻塞主线程,添加守护线程
import time
from threading import Thread
def f1():
print('任嘉伦')
time.sleep(0.1)
print('任嘉伦是我的偶像')
def f2():
print('好好学习')
time.sleep(2)
print('你就能见他了!')
if __name__ == '__main__':
# 创建线程
f1 = Thread(target=f1)
f2 = Thread(target=f2)
# 设置守护线程
f1.setDaemon(True)
f2.setDaemon(True)
# 启动线程
f1.start()
f2.start()
# 阻塞主线程----"我(主线程)等你(子线程)"
f1.join()
f2.join()
print('哈哈!')
# 结果:
# 任嘉伦
# 好好学习
# 任嘉伦是我的偶像
# 你就能见他了!
# 哈哈!
例5:多线程进阶,修改名字和获取名字
import time
from threading import Thread
def f1():
print('任嘉伦')
time.sleep(1)
print('任嘉伦是我的偶像')
def f2():
print('好好学习')
time.sleep(2)
print('你就能见他了!')
if __name__ == '__main__':
# 创建线程
f1 = Thread(target=f1)
f2 = Thread(target=f2)
# 启动线程
f1.start()
f2.start()
# 阻塞主线程----"我(主线程)等你(子线程)"
f1.join()
f2.join()
# 修改名字
f1.setName('Allen')
f2.setName('任国超')
# 获取名字
print(f1.getName())
print(f2.getName())
print('哈哈!')
#结果:
# 任嘉伦
# 好好学习
# 任嘉伦是我的偶像
# 你就能见他了!
# Allen
# 任国超
# 哈哈!
2.线程执行代码的封装
from threading import Thread
import time
class Ourthread(Thread):
# 重写run方法
def run(self):
print('任嘉伦')
time.sleep(7)
print('你们认识吗?')
if __name__ == '__main__':
t1 = Ourthread()
t1.start()
结果:
任嘉伦
你们认识吗?
3.结论
结论1:线程之间执行是无序的"
import threading # 导入线程模块
import time
def task():
time.sleep(2)
print(f'当前线程名为:{threading.current_thread().name}\n', end='')
# print(f'当前线程名为:{threading.current_thread().name}\n',end='')
if __name__ == '__main__':
for i in range(3):
# 创建线程
t = threading.Thread(target=task)
# 启动线程
t.start()
# 结果:执行第1次
# 当前线程名为:Thread-1
# 当前线程名为:Thread-3
# 当前线程名为:Thread-2
# 执行第2次:
# 当前线程名为:Thread-1
# 当前线程名为:Thread-2
# 当前线程名为:Thread-3
结论2:多线程资源共享
from threading import Thread # 导入线程模块的另一种方式
import time
list = [] # 全局变量,空列表
# 写数据
def writedata():
for i in range(5):
list.append(i) # 添加i到lst列表
time.sleep(0.2) # 睡眠0.2s
print('写入数据:',list)
# 读数据
def readdata():
print('读取的数据:',list)
if __name__ == '__main__':
# 创建线程
wd = Thread(target=writedata)
rd = Thread(target=readdata)
# 启动线程
wd.start()
rd.start()
# 结果:
# 读取的数据: [0](写数据还没写完,就读取了)
# 写入数据: [0, 1, 2, 3, 4]
结论3:线程之间存在资源竞争
from threading import Thread
a = 0
b = 1000000
def sum1():
for i in range(b):
global a
a += 1
print(f'第一次:{a}\n',end='')
def sum2():
for i in range(b):
global a
a += 1
print(f'第二次:{a}\n',end='')
# sum2()
if __name__ == "__main__":
# 创建线程
t1 = Thread(target=sum1)
t2 = Thread(target=sum2)
# 启动线程
t1.start()
t2.start()
# 结果:
# 第二次:1549492
# 第一次:1680705
Pass:资源竞争有什么解决的办法呢?
三、 互斥锁资源竞争解决的办法 :互斥锁
1、定义:
普通的,不使用线程:
a = 0
b = 1000000
def sum1():
for i in range(b):
global a
a += 1
print(f'第一次:{a}\n',end='')
sum1()#
def sum2():
for i in range(b):
global a
a += 1
print(f'第二次:{a}\n',end='')
sum2()
结果:
第一次:1000000
第二次:2000000
使用进程,互斥锁解决:
from threading import Thread,Lock
a = 0
b = 1000000
# 创建全局互斥锁
lock = Lock()
def sum1():
lock.acquire() # 加锁
for i in range(b):
global a
a += 1
print(f'第一次:{a}\n',end='')
lock.release() # 解锁
# sum1()
def sum2():
lock.acquire()
for i in range(b):
global a
a += 1
print(f'第二次:{a}\n',end='')
lock.release()
if __name__ == "__main__":
# 创建线程
t1 = Thread(target=sum1)
t2 = Thread(target=sum2)
# 启动线程
t1.start()
t2.start()
结果:
第一次:1000000
第二次:2000000
四、同步
1、定义:
使用join()解决:
from threading import Thread
a = 0
b = 1000000
def sum1():
for i in range(b):
global a
a += 1
print(f'第一次:{a}\n',end='')
def sum2():
for i in range(b):
global a
a += 1
print(f'第二次:{a}\n',end='')
if __name__ == "__main__":
# 创建线程
t1 = Thread(target=sum1)
t2 = Thread(target=sum2)
# 启动线程
t1.start()
t1.join() # 解决资源竞争join()方式
t2.start()
t2.join()
结果:
第一次:1000000
第二次:2000000
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)