1,多任务
多任务介绍
- target:表示调用对象,即子进程要执行的任务。
- args:表示调用的位置参数元组
程序中:
#如下程序,模拟唱歌跳舞
#没有多任务的程序
import time
def sing():
'''唱歌五秒钟'''
for i in range(5):
print('-----正在唱菊花残-------')
time.sleep(1)
def dance():
'''跳舞五秒钟'''
print('------正在跳小鸡舞------')
time.sleep(1)
def main():
sing()
dance()
if __name__=='__main__':
main()
怎样实现唱歌跳舞同时进行呢
import time
import threading
def sing():
'''唱歌五秒钟'''
for i in range(5):
print('-----正在唱菊花残-------')
time.sleep(1)
def dance():
'''跳舞五秒钟'''
for i in range(5):
print('------正在跳小鸡舞------')
time.sleep(1)
def main():
t1 = threading.Thread(target=sing)
t2 = threading.Thread(target=dance)
t1.start()
t2.start()
if __name__ == '__main__':
main()
多任务的概念:简单的说就是操作系统可以同时运行多个任务
cpu:电脑最核心的物理硬件。
单核CPU:同一时刻只做一件事情,时间片轮转,并发,假的多任务
双核CPU:同一时刻两件事情一起做,运行的程序数大于2的话也是并发
四核CPU:同一时刻四件事情一起做,
并行:真的多任务
并发:假的多任务
2,线程(重点与注意点)
@1重点
线程是执行代码的东西
一个程序运行起来之后,一定有一个执行代码的东西,这个东西称为线程
import threading
import time
#逐个输出,间隔一秒
def saySorry():
for i in range(5):#
print('--------i love you---------')
time.sleep(1)
def main():
t = threading.Thread(target=saySorry)
t.start() # 启动线程,即让线程开始执行
if __name__ == '__main__':
main()
import threading
import time
#一起输出,没有时间间隔
def saySorry():#5(子线程)
print('--------i love you---------')
time.sleeep(1)
def main():#2
for i in range(5):
t=threading.Thread(target=saySorry)#3
t.start()#4启动线程(主),即让线程开始执行
if __name__=='__main__':#1
main()
#定义函数不会执行,调用函数才会执行
写函数名 +():表示调用函数
只写函数名:表示告诉我函数在哪
import time
import threading
def sing():#6 子1
'''唱歌五秒钟'''
for i in range(5):
print('-----正在唱菊花残-------')
time.sleep(1)
def dance():#8 子2
'''跳舞五秒钟'''
for i in range(5):
print('------正在跳小鸡舞------')
time.sleep(1)
def main():#2
t1 = threading.Thread(target=sing)#3
t2 = threading.Thread(target=dance)#4
t1.start()#5 主1
t2.start()#7 主2
#主线程继续往下没有需要执行的,这时候需要等待子线程执行完。
if __name__ == '__main__':#1
main()
查看线程数量和线程信息
import time
import threading
def sing():#6 子1
'''唱歌五秒钟'''
for i in range(5):
print('-----正在唱菊花残-------')
time.sleep(1)
def dance():#8 子2
'''跳舞五秒钟'''
for i in range(5):
print('------正在跳小鸡舞------')
time.sleep(1)
def main():#2
t1 = threading.Thread(target=sing)#3
t2 = threading.Thread(target=dance)#4
t1.start()#5主1
t2.start()#7主2
#主线程继续往下没有需要执行的,这时候需要等待子线程执行完。
if __name__ == '__main__':#1
main()
while True:
length=len(threading.enumerate())#返回值是一个列表,列表有几个元素表示有几个线程
print('当前运行的线程数为:{}'.format(length))
if length<=1:
break
time.sleep(5)
names=['aa','bb','cc']
for temp in names:
print(temp)
#aa
#bb
#cc
for temp in enumerate(names):
print(names)
#(0,'aa')元组
#(1,'bb')
#(2,'cc')
a,b=(11,22)
print(a)#11
print(b)#22
#拆包
for i ,name in enumerate(names):
print(i,name)
#0 aa
#1 bb
#3 cc
import threading
def test1():
for i in range(5):#1
print('--------hahaha-------')
def test2():
for i in range(5):#2
print('--------hehehehehe----')
def main():
t1=threading.Thread(target=test1)
t2=threading.Thread(target=test2)
t1.start()
t2.start()
print(threading.enumerate())#3
if __name__=='__main__':
main()
#1,2,3会抢着运行,谁先运行看系统
线程执行顺序不确定
#可以通过适当延时,保证谁先执行
import threading
import time
def test1():
for i in range(5):#1
print('--------hahaha-------')
def test2():
for i in range(5):#2
print('--------hehehehehe----')
def main():
t1=threading.Thread(target=test1)
t2=threading.Thread(target=test2)
t1.start()#1
time.sleep(1)
t2.start()#2
time.sleep(1)
print(threading.enumerate())#3
if __name__=='__main__':
main()
#1,2,3顺序执行
#但是只能看到一个线程
如果想要看到多个线程,怎么办呢
#查看线程数,让某些线程先执行,循环查看当前运行的线程
import threading
import time
def test1():
for i in range(2):#1
print('--------hahaha-------')
time.sleep(1)#在此处打印一次循环一次
def test2():
for i in range(5):#2
print('--------hehehehehe----')
time.sleep(1)#在此处打印一次循环一次
def main():
t1=threading.Thread(target=test1)
t2=threading.Thread(target=test2)
t1.start()#1
t2.start()#2
while True:
print(threading.enumerate())#3
time.sleep(1)
if len(threading.enumerate())<=1:#用于退出循环
break
if __name__=='__main__':
main()
主线程结束程序才结束
子线程是在start开始才执行的
#验证创建线程以及运行时间
import threading
import time
def test1():
for i in range(2): # 1
print('--------hahaha-------')
time.sleep(1) # 在此处打印一次循环一次
def main():
#在调用Thread之前先打印当前线程信息
print(threading.enumerate())
t1 = threading.Thread(target=test1)#相当于准备过程,只能指定函数,不能指定类,但是是可以通过指定方式指定类,
# 在调用Thread之后打印
print(threading.enumerate())
t1.start() # 1,启动线程,让线程开始执行
# 在调用start之后打印
print(threading.enumerate()) # 3
if __name__ == '__main__':
main()
[<_MainThread(MainThread, started 14608)>]
[<_MainThread(MainThread, started 14608)>]
--------hahaha-------
[<_MainThread(MainThread, started 14608)>, <Thread(Thread-1, started 3288)>]
--------hahaha-------
#当调用Tread的时候不会创建线程
#当调用Tread的实例对象start方法的时候才会创建线程,以及让这个线程开始运行
指定类
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)
print(msg)
if __name__=='__main__':
t=MyThread()
t.start()
@2注意点:线程的封装
1,线程执行代码的封装
一个线程同一时刻只能执行一个程序
指定类
class MyThread(threading.Thread):
def run(self):
for i in range(3):
time.sleep(1)
msg="I'm"+self.name+'@'+str(i)
print(msg)
if __name__=='__main__':
t=MyThread()
t.start()
class MyThread(threading.Thread):
def run(self):
self.login=login
self.register=register
for i in range(3):
time.sleep(1)
msg="I'm"+self.name+'@'+str(i)
print(msg)
def login():
print('----jsjjsjs------')
def register():
print('----ieieieiei-----')
if __name__=='__main__':
t=MyThread()
t.start()#只执行run,如果还需要执行login和register,可以在run函数两边这样添加
2,重写多线程:
#重写多线程
import threading
class MyThread(threading.Thread):
def __init__(self,num):
threading.Thread.__init__(self)
# super(MyThread, self).__init__(self)
self.num=num
def run(self):
print('当前调用run方法')
self.num+=1
print('当前的线程中,获取的Num数据是',self.num)
if __name__ == '__main__':
t1=MyThread(0)#实例化对象
t2=MyThread(10)
t1.start()
t2.start()
#在多线程开发中,全局变量是多个线程共享的,局部变量是各自的线程的,不能共享
多进程重写时必须调用父类的__init__()
3,消费者生产者模式:
爬虫可以使用队列
通过队列实现生产者与消费者模式
# 同步的、线程安全的队列
import threading
from queue import Queue
class Producer(threading.Thread):
def run(self):
global que
while True:
if que.qsize() < 10:
que.put('这是生产者生产的数据')
class Consumer(threading.Thread):
def run(self):
global que
while True:
if que.qsize() > 0:
print(self.name, '消费数据', que.get())
pass
if __name__ == '__main__':
# 创建队列
que = Queue()
#生产数据
p=Producer()
p.start()
#消费数据
c=Consumer()
c.start()
线程怎样实现同步:上锁,协同工作