并发编程-多进程
一.进程新进程的创建都是由一个已经存在的进程执行了一个用于创建进程的系统调用而创建的。 1.在UNIX中:fork会创建一个与父进程一摸一样的副本 2.在Windows:系统调用CreateProcess创建进程 进程的状态 程序遇到IO操作(Input、output),会阻塞,IO完成会进入就绪状态,此时等待cpu执行。正在执行的程序时间片完(cpu切到其他程序执行),会进入就绪状态。 1.进程创建方式在windows环境下,开启进程必须在 if __name__ == "__main__"下 from multiprocessing import Process import time def task(name): print(f"{name} is running") time.sleep(3) print(f"{name} is gone") if __name__ == ‘__main__‘: p = Process(target=task,args=("alex",)) # 指定 这个线程去哪个函数里面去执行代码 p.start() #只是向操作系统发出一个开辟子进程的信号(由cpu执行进程中额任务),然后就执行下一行了 print("__main__") #操作系统在接受到信号之后,会在内存中开辟一个进程空间(新建一个子进程py文件),然后将主进程所有数据copy到子进程(相当于在子进程py文件中import主进程的所有内容,那么if __name__ == "__main__"下面的不会导过来),然后调用线程执行。 #开辟子进程的开销很大(时间很长),所以永远会执行主进程的代码。进程创建的方式一 from multiprocessing import Process import time class MyProcess(Process): def run(self): print(f"{self.name} is running") time.sleep(3) print(f"{self.name} is end") if __name__ == ‘__main__‘: p = MyProcess() p.start() # 会自动执行run方法(run方法相当于上面的task函数) print("__main__") #Process类中有name属性,默认为类名加上-1(MyProcess-1),每次新建一个子进程就MyProcess-2、MyProcess-3...进程创建的方式二 二.进程pid在pycharm中,父进程为pycharm,子进程为pycharm调用的python解释器。 import os import time print(f"子进程:{os.getpid()}") #运行此py文件的python解释器的pid print(f"父进程":{os.getppid()}) #当前pycharm的pidpycharm查看进程id from multiprocessing import Process import time import os def task(name): print(f‘子进程:{os.getpid()}‘) print(f‘主进程:{os.getppid()}‘) if __name__ == ‘__main__‘: p = Process(target=task,args=(‘常鑫‘,)) # 创建一个进程对象 p.start() # print(‘==主开始‘) print(f‘====主{os.getpid()}‘)示例代码 在cmd中,父进程为cmd,子进程为cmd调用的python解释器 #tasklist获取所有进程的pid #tasklist | findstr pycharm 指定获取某一个进程cmd查看进程id 三.进程之间的空间隔离进程之间相互隔离,是不能互相修改数据的 from multiprocessing import Process import time name = ‘太白‘ def task(): global name name = ‘刚子sb‘ print(f‘子进程{name}‘) if __name__ == ‘__main__‘: p = Process(target=task) # 创建一个进程对象 p.start() time.sleep(3) print(f‘主:{name}‘) #打印结果 #子进程刚子sb #主:太白示例代码 四.joinjoin就是阻塞,只有join执行完,才会执行join下面的主进程代码 from multiprocessing import Process import time def task1(name): print(f"{name} is running") time.sleep(1) print(f"{name} is gone") def task2(name): print(f"{name} is running") time.sleep(2) print(f"{name} is gone") def task3(name): print(f"{name} is running") time.sleep(3) print(f"{name} is gone") if __name__ == ‘__main__‘: start_time = time.time() p1 = Process(target=task1,args=("alex",)) p2 = Process(target=task2,args=(‘egon‘,)) p3 = Process(target=task3,args=(‘meet‘,)) p1.start() p2.start() p3.start() p1.join() p2.join() p3.join() print(time.time() - start_time) 打印结果 alex is running egon is running meet is running alex is gone egon is gone meet is gone 3.101801872253418 #我们看到,只执行了3s左右,因为p1.start(),p2.start(),p3.start()三个相当于并发执行,p1.join()执行的过程中p2,p3也会执行,其实就是并发。示例1 from multiprocessing import Process import time def task1(name): print(f"{name} is running") time.sleep(1) print(f"{name} is gone") def task2(name): print(f"{name} is running") time.sleep(2) print(f"{name} is gone") def task3(name): print(f"{name} is running") time.sleep(3) print(f"{name} is gone") if __name__ == ‘__main__‘: start_time = time.time() p1 = Process(target=task1,)) p1.start() p2.start() p3.start() p1.join() print("p1") p2.join() print("p2") p3.join() print("p3") print(time.time() - start_time) 打印结果: alex is running egon is running meet is running alex is gone p1 #1s执行打印p1 egon is gone p2 #第2s执行打印p2,因为p2已经执行了1s meet is gone p3 3.1154708862304688示例2 from multiprocessing import Process import time,random def task(): print("task begin") time.sleep(random.randint(1,2)) print("task end") if __name__ == ‘__main__‘: start_time = time.time() for i in range(3): p = Process(target=task) p.start() p.join() print("__main__") print(time.time() - start_time) # 上述例子为串行,每start()一次,就join一次,我们都知道,有join会等到join完成后再执行下面的代码。正确例子如下: from multiprocessing import Process import time,2)) print("task end") if __name__ == ‘__main__‘: start_time = time.time() lst = [] for i in range(3): p = Process(target=task) lst.append(p) p.start() for j in lst: j.join() print("__main__") print(time.time() - start_time)经典示例 五.进程的其他参数from multiprocessing import Process import time def task(name): print(f‘{name} is running‘) time.sleep(2) print(f‘{name} is gone‘) if __name__ == ‘__main__‘: # 在windows环境下,开启进程必须在 __name__ == ‘__main__‘ 下面 # p = Process(target=task,args=(‘常鑫‘,)) # 创建一个进程对象 p = Process(target=task,),name=‘alex‘) # 创建一个进程对象 p.start() time.sleep(1) p.terminate() # 杀死子进程(可以理解为发送信号,需要时间) *** p.join() # *** time.sleep(0.5) print(p.is_alive()) # 查看进程是否存活*** print(p.name) # 默认属性 p.name = ‘sb‘ print(p.name) print(‘==主开始‘)进程的其他参数 六.僵尸进程和孤儿进程基于UNIX环境(linux,macOs) 二.守护进程p.daemon = True,将子进程p设置为守护进程,只要主进程结束(严格来说应该是主进程中的任务执行完,而非主进程结束),守护进程也跟着结束 (编辑:ASP站长网) |