母婴用品网站建设,wordpress开启侧边栏,wordpress 菜单 导出,界面设计与制作是做什么的在现实社会#xff0c;我们经常需要一种场景#xff0c;就是同时有多个事情需要执行#xff0c;如在浏览网页的同时需要听音乐。比如说在跳舞的时候要唱歌。同样的#xff0c;在程序中我们也可能需要这种场景。如下面我们以同时听音乐和浏览网页为例。def network():while …在现实社会我们经常需要一种场景就是同时有多个事情需要执行如在浏览网页的同时需要听音乐。比如说在跳舞的时候要唱歌。同样的在程序中我们也可能需要这种场景。如下面我们以同时听音乐和浏览网页为例。def network():while True:print(正在上网~~~)time.sleep(1)def sing():while True:print(正在听歌……)time.sleep(1)if __name__ __main__:network()sing()执行代码我们发现代码并没有按照我们的想法执行而是一直执行上网的代码这样就无法完成我们想要的效果。如果你想要同时听音乐和浏览网页两件事就需要一个新的方式来完成这个方式就是----多任务。多任务是咋回事呢什么叫做多任务呢简单的说就是操作系统(OS)可以同时运行多个任务。如你可以一边浏览网页一边听着歌同时还可以使用画板画着画这个就是多任务。其实我们的操作系统就是多任务只是我们都没有注意罢了。单核CPU中1、时间片轮换2、优先级别调度3、多核CPU中4、并发5、并行Fork子进程编写完的代码在没有运行的情况下称之为程序。正在运行的代码就成为了进程。进程除了包含代码外还需要运行环境等所以和程序是存在区别的。Python在os模块上封装了常用的系统调用其中就包括了fork我们可以很轻松地在Python代码中创建进程。# 注意下面代码只能在Linux、Mac系统上运行window下不支持运行import osimport time# 使用os模块的fork方法可以创建一个新的进程pid os.fork()if pid 0:while True:print(son process, pid) # 子进程代码time.sleep(1)else:while True:print(main process, pid) # 父进程代码time.sleep(1)Python中的fork() 函数可以获得系统中进程的PID ( Process ID )返回0则为子进程否则就是父进程然后可以据此对运行中的进程进行操作但是强大的 fork() 函数在Windows版的Python中是无法使用的。。。只能在Linux系统中使用比如 Ubuntu 15.04Windows中获取父进程ID可以用 getpid()。getpid、getppid我们可以使用os模块的getpid来获取当前进程的进程编号同样也可以使用os.getppid()方法案来获取当前进程的父进程编号。import osimport time# 使用os模块的fork方法可以创建一个新的进程pid os.fork()if pid 0:while True:print(我是子线程我的编号是%s我的父进程编号是%s(os.getpid(),os.getppid()))time.sleep(1)else:while True:print(我是父线程我的编号是%s我的子进程编号是%s %(os.getpid(), pid))time.sleep(1)使用os模块中的getpid()方法可以得到当前线程的编号使用getppid()方法可以得到该线程的父级编号。多进程修改全局变量多进程修改全局变量import osimport time# 使用os模块的fork方法可以创建一个新的进程pid os.fork()if pid 0:while True:print(我是子线程我的编号是%s我的父进程编号是%s %(os.getpid(),os.getppid()))time.sleep(1)else:while True:print(我是父线程我的编号是%s我的子进程编号是%s %(os.getpid(), pid))time.sleep(1)使用os模块中的getpid()方法可以得到当前线程的编号使用getppid()方法可以得到该线程的父级编号。多进程修改全局变量import os# 定义一个全局变量num 0pid os.fork()if pid 0:# 子进程num 1print(子进程~~~~~~,num)else:#父进程num 1print(父进程~~~~~~, num)输出结果如下父进程~~~~~~ 1子进程~~~~~~ 1由此可见进程间是无法共享数据的。注意多个进程间每个进程的所有数据(包括全局变量)都是各自拥有一份的互不影响。完成最开始的任务import osimport timedef network():for x in range(5):print(正在上网~~~)time.sleep(1)def singe():for x in range(5):print(正在听歌……)time.sleep(1)pid os.fork()if pid 0:network()else:singe()print(程序结束~~~)多个fork问题上面的所有程序中我们使用了fork函数生成了两个进程(一个主进程、一个子进程)但是如果我们在程序中需要多个进程呢如两次调用fork函数会生成三个进程吗import os,timeres os.fork()if res 0:print(一个子线程)else:print(主线程)ret os.fork()if ret 0:print(第三个线程)else:print(第四个线程)结果如下主线程第四个线程第三个线程一个子线程第三个线程第四个线程我们发现主线程和子线程各执行了一次但是第三个和第四个都执行了两次为什么了看下面的图。1.png主进程和子进程的执行顺序其实通过上面的代码我们已经发现了主进程和子进程的执行顺序是没有规律的这个不受程序员的控制有操作系统的调度算法来控制。multiprocessing前面我们使用os.fork()方法实现了多进程但是这种方案只能在Linux下运行window环境下是无法运行的那么有没有可以实现在任何平台都能运行的多进程了有Python为大家提供了multiprocessing模块用来实现多进程。函数实现方式from multiprocessing import Processimport osdef run():print(这个是一个独立的进程,os.getpid(),os.getppid())if __name__ __main__:print(代码开始运行……)task Process(targetrun)task.start() # 启动进程print(代码运行结束……,os.getpid())结果如下2.png我们发现主进程结束后子进程才结束说明我们确实开辟了一个独立的进程。from multiprocessing import Processimport osdef run(msg):for x in range(5):print(这个是一个独立的进程,os.getpid(),os.getppid())print(传递的参数是,msg)else:print(子进程结束了……)if __name__ __main__:print(代码开始运行……)# target表示独立进程的方法#args表示要传递的参数注意args的类型是元组,也支持列表listtask Process(targetrun,args(这个是参数,))task.start() # 启动进程print(代码运行结束……,os.getpid())args为调用的子进程的函数的参数注意类型是一个元组。from multiprocessing import Processimport osdef run(msg):for x in range(5):print(这个是一个独立的进程,os.getpid(),os.getppid())print(传递的参数是,msg)else:print(子进程结束了……)if __name__ __main__:print(代码开始运行……)# target表示独立进程的方法#args表示要传递的参数注意args的类型是元组task1 Process(targetrun,args(这个是参数1,))task1.start() # 启动进程task2 Process(targetrun, args(这个是参数2,))task2.start() # 启动进程task3 Process(targetrun, args(这个是参数3,))task3.start() # 启动进程print(代码运行结束……,os.getpid())多个进程启动还是一样执行的顺序同样不可控。(主进程等待子进程版)join方法表示只有子进程执行完成后主进程才能结束。主进程会等待子进程完成后自身才会执行完成。from multiprocessing import Processimport os,timedef run(msg):print(子进程开始执行了……)time.sleep(3)print(子进程执行end了……)if __name__ __main__:print(代码开始运行……)task1 Process(targetrun,args(这个是参数1,))print(task1.is_alive()) # is_alive()方法判断进程是否结束task1.join() # 表示这个子进程执行完成主进程才能继续向下执行print(task1.is_alive())print(代码运行结束……,os.getpid())常用方法from multiprocessing import Processimport os,timedef run(msg):print(子进程开始执行了……)time.sleep(3)print(子进程执行end了……)if __name__ __main__:print(代码开始运行……)# name表示我们认为的为这个子进程取个名称# 如果不写默认是Process-n n从1开始task1 Process(targetrun,args(这个是参数1,),nameliujianhong)task1.start() # 启动进程print(task1.is_alive()) # is_alive()方法判断进程是否结束task1.join() # 表示这个子进程执行完成主进程才能继续向下执行print(task1.name) # 得到子进程的名称task1.terminate() # 强制结束进程print(task1.is_alive())print(代码运行结束……,os.getpid())多个进程使用不同的方法版from multiprocessing import Processimport os,timedef run(msg):print(子进程1开始执行了……)time.sleep(3)print(子进程1执行end了……)def run2(msg):print(子进程2开始执行了……)time.sleep(3)print(子进程2执行end了……)if __name__ __main__:print(代码开始运行……)task1 Process(targetrun,args(这个是参数1,))task1.start() # 启动进程task2 Process(targetrun2, args(这个是参数2,))task2.start() # 启动进程print(代码运行结束……,os.getpid())类实现方式在Python中很多的方案都提供了函数和类两种实现方式如装饰器、自定义元类。同样多进程也有两种实现前面我们已经看了使用函数实现的方式下面我们使用类来实现以下呗。进程类的实现非常的简单只要继承了Process类就ok了重新该类的run方法run方法里面的代码就是我们需要的子进程代码。from multiprocessing import Processimport timeclass MyProcess(Process):# 重写run方法即可def run(self):print(一个子进程开始运行了)time.sleep(1)print(一个子进程开始运行结束了)if __name__ __main__:task MyProcess()task.start()print(主进程结束了……)在进程类的实现中如果想要初始化一些前面我们提到过的参数如进程名称等可以使用init借助父类来完成。from multiprocessing import Processimport timeclass MyProcess(Process):def __init__(self,name):super().__init__(namename)# 重写run方法即可def run(self):print(一个子进程开始运行了)time.sleep(1)print(一个子进程开始运行结束了)if __name__ __main__:task MyProcess(刘建宏)task.start()print(task.name)print(主进程结束了……)进程池Pool当我们需要的进程数量不多的时候我们可以使用multiprocessing的Process类来创建进程。但是如果我们需要的进程特别多的时候手动创建工作量太大了所以Python也为我们提供了Pool(池)的方式来创建大量进程。from multiprocessing import Poolimport os,timedef run(msg):print(开始一个子线程运行了……)time.sleep(1)print(开始一个子线程运行结束了……)if __name__ __main__:pool Pool(3) # 表示初始化一个进程池最大进程数为5for x in range(10):pool.apply_async(run, args(hello pool,))print(------start----)pool.close() # 关闭池pool.join() # 等待所有的子进程完成必须放在close后面print(-------end------)注意一般我们使用apply_async这个方法表示非阻塞的运行一旦使用了apply方法表示阻塞式执行任务此时就是单任务执行了(一般不会使用特殊场景才会使用)