千家信息网

python怎么像线程一样管理进程

发表于:2025-01-19 作者:千家信息网编辑
千家信息网最后更新 2025年01月19日,本篇内容主要讲解"python怎么像线程一样管理进程",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"python怎么像线程一样管理进程"吧!一、创建一个进程
千家信息网最后更新 2025年01月19日python怎么像线程一样管理进程

本篇内容主要讲解"python怎么像线程一样管理进程",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"python怎么像线程一样管理进程"吧!

一、创建一个进程

要创建一个进程,最简单的方式是用一个目标函数实例化一个Process对象,然后与threading一样调用start()函数让它工作。示例如下:

import multiprocessingdef worker():    for i in range(3):        print(i)if __name__=="__main__":    p = multiprocessing.Process(target=worker)    p.start()

需要注意的是,multiprocessing库在Windows创建进程必须在if __name__=="__main__":中,这是 Windows 上多进程的实现问题。在 Windows 上,子进程会自动 import 启动它的这个文件,而在 import 的时候是会执行这些语句的。如果直接创建就会无限递归创建子进程报错。所以必须把创建子进程的部分用那个 if 判断保护起来,import 的时候 __name__ 不是 __main__ ,就不会递归运行了。

二、设置进程名

在threading线程中,我们可以通过其参数name设置线程名,同样的我们也可以通过name参数设置其进程的名字。示例如下:

import multiprocessingimport timedef worker():    print(multiprocessing.current_process().name, "start")    time.sleep(2)    print(multiprocessing.current_process().name, "end")if __name__ == "__main__":    p1 = multiprocessing.Process(name='p1', target=worker)    p2 = multiprocessing.Process(name='p2', target=worker)    p3 = multiprocessing.Process(name='p3', target=worker)    p1.start()    p2.start()    p3.start()

三、守护进程

和线程一样,在所有子进程没有退出之前,主程序是不会退出的。有时候,我们可能需要启动一个后台进程,它可以一直运行而不阻塞主程序退出。

要标志一个守护进程,可以将其添加第3个参数daemon,设置为True。默认值为False,不作为守护进程。示例如下:

import multiprocessingimport timedef worker():    print(multiprocessing.current_process().name, "start")    time.sleep(1)    print(multiprocessing.current_process().name, "end")def worker2():    print(multiprocessing.current_process().name, "start")    time.sleep(2)    print(multiprocessing.current_process().name, "end")if __name__ == "__main__":    p1 = multiprocessing.Process(name='p1', target=worker)    p2 = multiprocessing.Process(name='p2', target=worker2, daemon=True)    p3 = multiprocessing.Process(name='p3', target=worker2, daemon=True)    p1.start()    p2.start()    p3.start()

p2,p3为守护进程,但p1不是所以执行1秒之后,就退出主程序了,也就没有打印p2p3的内容。但是其依旧在执行中,直到执行完成。

四、join()

同样的,如果你期望强制等待一个守护进程的结束,可以增加join()函数。还是上面的代码,示例如下:

import multiprocessingimport timedef worker():    print(multiprocessing.current_process().name, "start")    time.sleep(1)    print(multiprocessing.current_process().name, "end")def worker2():    print(multiprocessing.current_process().name, "start")    time.sleep(2)    print(multiprocessing.current_process().name, "end")if __name__ == "__main__":    p1 = multiprocessing.Process(name='p1', target=worker)    p2 = multiprocessing.Process(name='p2', target=worker2, daemon=True)    p3 = multiprocessing.Process(name='p3', target=worker2, daemon=True)    p1.start()    p2.start()    p3.start()    p1.join()    p2.join()    p3.join()

运行之后,和设置进程名的运行结果一样,这里不在展示。唯一与守护进程代码的区别就是最后三行join()函数代码。当然,也可以像线程一样,给join()函数传入一个时间,超过这个时间,主进程不再等待。

五、强制结束进程

如果一个进程已经挂起或者不小心进入了死锁状态,那么这个时候,我们往往会强制的结束进程。对一个进程对象调用terminate()会结束子进程。示例如下:

import multiprocessingimport timedef worker():    print(multiprocessing.current_process().name, "start")    time.sleep(5)    print(multiprocessing.current_process().name, "end")if __name__ == "__main__":    p1 = multiprocessing.Process(name='p1', target=worker)    p1.start()    print("是否还在运行", p1.is_alive())    p1.terminate()    print("是否还在运行", p1.is_alive())    p1.join()    print("是否还在运行", p1.is_alive())

终止进程后要使用join()函数等待进程的退出。使进程管理代码有足够的时间更新对象的状态,以反应进程已经终止。

六、进程退出状态码

进程退出时,生成的状态码可以通过exitcode属性访问。下表就是其状态码的取值范围以及其意义:

退出码含义
0未生成任何错误
>0进程有一个错误,并以该错误码退出
<0进程以一个-1*exitcodde信号结束

测试如下:

import multiprocessingimport timedef worker():    print(multiprocessing.current_process().name, "start")    time.sleep(5)    print(multiprocessing.current_process().name, "end")if __name__ == "__main__":    p1 = multiprocessing.Process(name='p1', target=worker)    p2 = multiprocessing.Process(name='p2', target=worker)    p1.start()    p2.start()    print("是否还在运行", p1.is_alive())    p1.terminate()    print("是否还在运行", p1.is_alive())    print(p1.exitcode)    p1.join()    print("是否还在运行", p1.is_alive())    print(p1.exitcode)    time.sleep(5.5)    print(p2.exitcode)

可以看到,强制退出的进程状态码为负数,正常退出的进程状态码为0。

七、日志

调试并发问题时,如果能够访问multiprocessing所提供对象的内部状态,那么这会很有用。在实际的项目中,我们可以使用一个方便的模块级函数启用日志记录,它使用logging建立一个日志记录器对象,并增加一个处理器,使日志消息被发送到标准错误通道。

示例如下:

import multiprocessingimport loggingimport sysdef worker():    print("运行工作进程")    sys.stdout.flush()if __name__ == "__main__":    multiprocessing.log_to_stderr(logging.DEBUG)    p1 = multiprocessing.Process(name='p1', target=worker)    p1.start()    p1.join()

八、派生进程

与线程一样,我们可以自定义进程,而不必只是传入一个函数进行进程的创建。

创建的进程的方式也是派生自进程类即可。示例如下:

import multiprocessingclass WorkerProcess(multiprocessing.Process):    def run(self):        print(self.name)        returnif __name__ == "__main__":    for i in range(5):        p = WorkerProcess()        p.start()        p.join()

到此,相信大家对"python怎么像线程一样管理进程"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

0