我们写的程序大多是单个.py文件,在执行过程中,程序会顺着代码行执行,但是如果我们想要让一个.py文件同时干两件事情呢?这就需要使用多进程和多线程
先简单的概述一下进程和线程:
一个进程总是有多个线程(至少一个),但一个线程不能单独存在,必须在一个进程中。使用windows系统的小伙伴们可以用鼠标在任务栏上右键一下,然后单击‘任务管理器’,再点击‘性能’,就可以看到当前电脑所运行的进程数和线程数啦!那么就让我们先来看看多线程↓↓↓
导入threading后调用threading.Thread函数,生成一个Thread对象(记住,开头的t一定要大写)
import threading
#这里我们创建一个Thread对象t1
t1 = threading.Thread(target = xxx,args = (xxx))
这个函数有个关键字参数,target必传,是执行函数的名称(通常我们把一个线程中要执行的东西放在一个函数里面),函数名最好不要用引号引着。args是此函数的参数,如果没有,可以不填
现在就可以启动这个线程了
#启动线程t1
t1.start()
调用该对象的start函数,即可启动这个线程。线程启动后,不会耽误下面的语句执行
这里我们来举一个例子,比如我想让程序同时打印出来一些东西,执行5次:
import threading
def f1(i):
print('线程f1执行第%d次'%(i+1))
def f2(i):
print('线程f2执行第%d次'%(i+1))
for x in range(5):
#创建Thread对象,可以重复创建,但是不可以重复启动(再次创建后会刷新)
t1 = threading.Thread(target = f1,args = [x])
t2 = threading.Thread(target = f2,args = [x])
#启动线程
t2.start()
t1.start()
我们来看一下效果:
线程f2执行第1次
线程f1执行第1次
线程f2执行第2次
线程f1执行第2次
线程f2执行第3次
线程f1执行第3次
线程f2执行第4次
线程f1执行第4次
线程f2执行第5次
线程f1执行第5次
可以看到,函数f1和f2同时执行了。
不过,Python有个利大于弊的东西,叫全局解释器锁(GIL),他保证了Python同一时刻只执行一条线程,尽管我们目测是在同时执行。这时就要使用多进程
先使用pip安装multiprocessing模块
pip install multiprocessing
然后做的事情和多线程类似
#导入模块
from multiprocessing import Process
#创建Process对象
p1 = Process(target = xxx,args = (xxx))
启动进程的方法也与多线程相似
#启动线程p1
p1.start()
我们还用上面那个例子,改成多进程
#导入模块
from multiprocessing import Process
def p1(i):
print('进程p1执行第%d次'%(i+1))
def p2(i):
print('进程p2执行第%d次'%(i+1))
for x in range(5):
#划重点!任何Windows系统用户都应该加上!!
#表示这个程序是直接执行的,而不是导入
if __name__ == '__main__':
#创建进程对象
t1 = Process(target = p1,args = [x])
t2 = Process(target = p2,args = [x])
#启动进程
t2.start()
t1.start()
创建和启动进程时前面要加上if __name__ == '__main__':,__name__是每个.py文件都有的一个变量,当它等于'__main__'时,表示这个程序是你直接运行的,当它等于这个文件名时,表示这个文件是以导入的形式去运行的。比如我有一个文件叫1.py,那么当我使用import关键字来导入它时,这个1.py的__name__变量就等于1.py,而不是__main__
看看效果
进程p1执行第1次
进程p2执行第1次
进程p2执行第2次
进程p1执行第2次
进程p2执行第3次
进程p1执行第3次
进程p2执行第4次
进程p1执行第4次
进程p2执行第5次
进程p1执行第5次
虽然效果差不多,但这充分利用了CPU进程池,且避开了GIL的影响
其实有关线程的还有一个东西,还有一个东西,叫线程锁,他可以阻塞线程,让他执行完毕后再释放开。更多细节可以再看一看其他文章。
今天就介绍到这里,大家再见!