1、 线程进程的概述
操作系统每次运行一个程序的时候,他都会给程序准备一个内存,然后这个内存里专门放程序里面执行过程中产生的变量。
这个内存区域可以被认为是xxx进程,然后在进程里面又有若干个线程来帮我们工作(至少有一个)。所以进程是一个资源单位,而线程是执行单位,CPU在跑的时候执行的是线程。
当我们创建一个进程,如果不创建线程行不行? 答案当然是不行的,可以把进程比做一个公司,为了能让公司运行起来,必须至少有一个员工(线程),当在程序执行的时候,一个线程不够用,则需要多创建几个线程,这就是多线程的概念。
每次创建程序的时候,都有一个主线程在里面(main)
2、下面给出一个案例,观察是否为多线程程序
def func():
for i in range(1000):
print("func",i)
if __name__ == '__main__':
func()
for i in range(1000):
print("main",i)
通过观察程序执行的过程,程序执行的时候,首先去生成func,然后在主线程里会再回到func函数去执行,执行完后再回到main里再往下执行,所以这是一根线的进程,单线程,不是多线程。
运行结果也可以看出是先执行func再执行main。
3、多线程的两种创建方法
方法一:导包Thread
# 进程,线程
# 进程是资源单位,每一个进程至少有一个线程
# 线程是执行单位
# 启动每一个程序默认都会有一个主线程
#多线程
from threading import Thread # 线程类
def func():
for i in range(1000):
print("func",i)
if __name__ == '__main__':
#创建线程类对象,并告诉程序你当前的线程,如果要执行的话,要执行谁 。
#target=后面的子线程不能加括号 加括号相当于返回值做参数,不加括号相当于函数本身做参数。
T = Thread(target=func) #创建线程,并给线程分配任务,
'''
Thread相当与公司招了一个新员工,新线程
target=func 相当于告诉新员工,如果你开始执行,你该干什么事情
同时呢,招完员工后自己该干什么事继续去干
'''
T.start() #多线程的状态为可以开始工作状态,具体的执行时间还得由CPU决定
for i in range(1000):
print("main",i)
通过运行结果发现,func和main两个线程在一起执行,因为打印的地方都是在控制台,所以会出现重叠的过程。
方法二:自己创建类 MyThread
from threading import Thread # 线程类
class MyThread(Thread): #继承Thread
'''
MyThread是我们自己创建的类,我们的类继承Thread就相当于是Thread的子类
所以我们写的类就会有Thread的特性
(子承父业)
'''
# 重写Thread里的run方法
def run(self): #当线程被执行的时候,被执行的就是run()
for i in range(1000):
print("子线程", i)
if __name__ == '__main__':
T = MyThread()
#T.run() #方法的调用 单线程
T.start() #开启线程
for i in range(1000):
print("主线程",i)
运行结果也是一样的。
4、多线程的创建(传参)
当我们需要传入两个线程的时候,如果是以下这种方法很难看出哪个是哪个。
from threading import Thread
def func():
for i in range(1000):
print("func",i)
if __name__ == '__main__':
T1 = Thread(target=func)
T1.start()
T2 = Thread(target=func)
T2.start()
【运行结果】
显示的都是func,并不知道t1和t2分别是哪个
这个时候就需要用到传参的方法了。 只需要在传入线程的时候,增加一个参数(args)用来确认线程的名字就可以了,需要注意的是,args对应的值必须是元组。
from threading import Thread
def func(name):
for i in range(1000):
print(name,i)
if __name__ == '__main__':
T1 = Thread(target=func,args=("王力宏",)) # 传入参数必须是元组的形式
T1.start()
T2 = Thread(target=func,args=("周杰伦",))
T2.start()
这样就可以很清楚的知道每个线程的名字了。
5、多进程的创建
相对于多线程,多进程会用到的更少一点,因为开辟进程,相对与开辟线程,所用到的资源要多的多,因为要开内存。
多进程的创建和多线程相似,只是导入的包不同
from multiprocessing import Process #进程类
def func():
for i in range(20000):
print("子进程",i)
if __name__ == '__main__':
P = Process(target=func)
P.start()
for i in range(20000):
print("主进程",i)
【运行结果】