Python的多进程运行
微信关注公众号:夜寒信息
致力于为每一位用户免费提供更优质技术帮助与资源供给,感谢支持!
这次给大家分享Python的多进程执行,由于Python基础已经讲述,不再赘述类,方法,及其他基础语法的概念。多进程在任务的执行使用非常广泛,比如Windows可以同时开很多的窗口,QQ,微信,游戏等。以后我们也会讲解多线程,多线程常用于下载,以后会有讲解。
要使用多线程我们需要引入一个库multiprocessing,在其中我们需要用到Process类来进行创建进程等一系列操作。我们还需要os库来获得进程的PID和PPID方便我们理解多进程概念。同时我们需要使sleep()方法来设置休眠时间,不然CPU运行太快,不利于我们观察,因此引入用time库。于是我们使用如下语句导入:
import os
from multiprocessing import Process
from time import sleep
在这里我们先演示两个进程的多进程,于是我们先创建两个进程所执行内容的函数,函数内具体需求可自定义。我们只简单打印文本内容:
def task1():
while True:
sleep(1)
print('这是任务1\tPID:', os.getpid(), '\tPPID:', os.getppid())
def task2():
while True:
sleep(1)
print('这是任务2\tPID:', os.getpid(), '\tPPID:', os.getppid())
其中os.getpid()和os.getppid()方法分别为得到进程的pid和ppid号,如果想要深入了解PID和PPID可以去学习操作系统,里面有详细概念。在这里我们引入PID和PPID是为了便于观察,理解。我们设置sleep(1),妹执行一个任务休眠一秒。在这里我们已经创建了两个任务,但还未创建进程,下面会讲解如何创建进程。
我们使用Process类来创建进程,同时传入target参数来添加任务,target传入你创建的函数名称,切忌加() 不然是传入函数的执行结果,而非函数。同时可以传入name参数,命名你的任务名称,至于name参数的用处,我会在下一节讲解。下面我们来进行创建:
p1 = Process(target=task1, name='任务1')
p2 = Process(target=task2, name='任务2')
p1.start()
p2.start()
这里我们在实例化对象后使用了start()方法,这是添加创建进程,并且执行进程。同时还有run()方法。但它只能执行,却没有添加进程。我在这里给大家演示一下,注意区别。
首先我们使用start()方法:
import os
from multiprocessing import Process
from time import sleep
def task1():
while True:
sleep(1)
print('这是任务1\tPID:', os.getpid(), '\tPPID:', os.getppid())
def task2():
while True:
sleep(1)
print('这是任务2\tPID:', os.getpid(), '\tPPID:', os.getppid())
if __name__ == '__main__':
# 子进程
p1 = Process(target=task1, name='任务1')
p2 = Process(target=task2, name='任务2')
p1.start()
p2.start()
运行结果为:
可以看到他在无限次的执行两个进程,我们再来使用run()方法:
import os
from multiprocessing import Process
from time import sleep
def task1():
while True:
sleep(1)
print('这是任务1\tPID:', os.getpid(), '\tPPID:', os.getppid())
def task2():
while True:
sleep(1)
print('这是任务2\tPID:', os.getpid(), '\tPPID:', os.getppid())
if __name__ == '__main__':
# 子进程
p1 = Process(target=task1, name='任务1')
p2 = Process(target=task2, name='任务2')
p1.run()
p2.run()
可以看到他在无限次的执行第一个任务,它只执行任务,却未启动进程。
上述我们已经可以启动多进程了,但我们的sleep的时间为固定的1,我们可以传参数来改变他吗,当然。Process类还可以传入args参数,args接收一个可迭代的元组所以格式为args=(1, )。我们将sleep的事件设置为n,假设他依旧休眠1秒,则它修改后的代码为:
import os
from multiprocessing import Process
from time import sleep
def task1(s):
while True:
sleep(s)
print('这是任务1\tPID:', os.getpid(), '\tPPID:', os.getppid())
def task2(s):
while True:
sleep(s)
print('这是任务2\tPID:', os.getpid(), '\tPPID:', os.getppid())
if __name__ == '__main__':
# 子进程
p1 = Process(target=task1, name='任务1', args=(1,))
p2 = Process(target=task2, name='任务2', args=(1,))
p1.start()
p2.start()
这样执行的内容和我们刚才的一样,但我们可以自由地传输参数,大家可以根据自己的需求传参。
** 那我们如何使进程停止呢,Process还有一个方法为terminate()它可以发出终止信号,以此来告诉我们的进程需要停止。为了观察的更方便,我们可以在主进程设置一个计数器,让程序先运行一段时间再结束。
import os
from multiprocessing import Process
from time import sleep
def task1(s):
while True:
sleep(s)
print('这是任务1\tPID:', os.getpid(), '\tPPID:', os.getppid())
def task2(s):
while True:
sleep(s)
print('这是任务2\tPID:', os.getpid(), '\tPPID:', os.getppid())
number = 1
if __name__ == '__main__':
# 子进程
p1 = Process(target=task1, name='任务1', args=(1,))
p2 = Process(target=task2, name='任务2', args=(1,))
p1.start()
p2.start()
while True:
number += 1
sleep(0.1)
if number == 100:
p1.terminate()
p2.terminate()
break
运行结果如下:
多进程的每个进程是互不干扰的,自己在处理的任务,别人无法干预,怎么去解释这一点呢。我们可以设置一个全局变量,在两个进程内都使用这个全局变量,我们再来print查看变量的值的变化:
import os
from multiprocessing import Process
from time import sleep
m = 1
def task1(s):
global m
while True:
sleep(s)
print('任务1的m值:', m)
m += 1
print('这是任务1\tPID:', os.getpid(), '\tPPID:', os.getppid())
def task2(s):
global m
while True:
sleep(s)
print('任务2的m值:', m)
m += 1
print('这是任务2\tPID:', os.getpid(), '\tPPID:', os.getppid())
number = 1
if __name__ == '__main__':
print('主进程的m值:', m)
# 子进程
p1 = Process(target=task1, name='任务1', args=(1,))
p2 = Process(target=task2, name='任务2', args=(1,))
p1.start()
p2.start()
while True:
number += 1
sleep(0.1)
if number == 100:
p1.terminate()
p2.terminate()
break
我们可以看到,虽然我们使用global m引用了全局变量,但我们的每一个进程的m值都是互不干扰,齐头并进的。
同时,我们可以看系统出并不是按你的实例化顺序调用进程,进程的调用是系统随机的,谁先到,谁先被调用。
下面给出完整代码及注释:
'''
process = Process(target = 函数名, name = 进程名, args = 传入参数
process 对象
对象调用:
process.start() 启动进程并执行任务
process.run() 执行任务,但未启动进程
terminate() 终止
'''
import os
from multiprocessing import Process
from time import sleep
m = 1
def task1(s):
global m
while True:
sleep(s)
m += 1
print('这是任务1\tPID:', os.getpid(), '\tPPID:', os.getppid())
def task2(s):
global m
while True:
sleep(s)
m += 1
print('这是任务2\tPID:', os.getpid(), '\tPPID:', os.getppid())
number = 1
if __name__ == '__main__':
# 子进程
p1 = Process(target=task1, name='任务1', args=(1,))
p2 = Process(target=task2, name='任务2', args=(1,))
p1.start()
p2.start()
while True:
number += 1
sleep(0.1)
if number == 100:
p1.terminate()
p2.terminate()
break
若有问题请关注微信公众号"夜寒信息"
微信关注公众号:夜寒信息
致力于为每一位用户免费提供更优质技术帮助与资源供给,感谢支持!