进程与多进程

it2022-05-05  147

python并发编程之进程

一、进程中的名词要清楚在程序中是什么意思?

进程与程序的区别:程序仅仅只是一堆代码而已,而进程指的是程序的运行过程. 进程:一个程序在一个数据集上的一次动态执行过程. ***(需要强调的是:同一个程序执行两次,那也是两个进程)***

并发与并行

并发:是伪并行,即看起来是同时运行,单个cpu+多道技术就可以实现并发,(并行也属于并发) 并行:同时运行,只有具备多个cpu才能实现并行

同步与异步:

同步执行:一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行。 异步执行:一个进程在执行某个任务时,另外一个进程无需等待其执行完毕,就可以继续执行,当有消息返回时,系统会通知进行处理,这样可以提高执行效率

进程的创建

multiprocessing模块介绍

multiprocess模块的功能众多:支持子进程,通信和共享数据,执行不同形式的同步,提供了process、Queue、Lock等组件。

多进程的创建

简单的两种方法:函数(直接代入运行)和用类类包装进程对象(继承) from multiprocssing import Process import time #1.函数(直接代入运行) def foo(i): print("say hi", i ) if __name__ =="__main__": for i in range(10): p1 = Process(target=foo, args=(i,)) p2 = Process(target=foo, args=(i,)) p1.start() p2.start() #2用类来包装进程对象(Process继承) class MyProcess(Process): def __init__(self,arg): super(MyProcess,self).__init__() self.arg = arg def run(self): print("say hi", i) time.sleep(1) if __name__=="__main__": for i in range(10): p1 = MyProcess(i) p2 = MyProcess(i) p1.start() #start会自动调用run p2.start()

daemon程序对比结果

#不加daemon守护进程 def foo(i): ''' 第一个方法:直接传入要运行的方法 :param i: :return: ''' print("say hi", i) if __name__ =="__main__": for i in range(2): p = multiprocessing.Process(target=foo,args=(i,)) #target --要执行的方法 p.start() #start --启动进程 print("end") #结果: end say hi 0 say hi 1 ========================================================================================= #加daemon守护进程 def foo(i): ''' 第一个方法:直接传入要运行的方法 :param i: :return: ''' print("say hi", i) if __name__ =="__main__": for i in range(10): p = multiprocessing.Process(target=foo,args=(i,)) #target --要执行的方法 p.daemon = True #守护进程 p.start() #start --启动进程 print("end") #结果: end 注: 因子进程设置了daemon属性,主进程结束,它们就随着结束了 ========================================================================================= #加daemon守护进程并做修改 def foo(i): ''' 第一个方法:直接传入要运行的方法 :param i: :return: ''' print("say hi", i) if __name__ =="__main__": for i in range(2): p = multiprocessing.Process(target=foo,args=(i,)) #target --要执行的方法 p.daemon = True #守护进程 p.start() #start --启动进程 p.join() #join()方法可以等待子进程结束后再继续往下运行 print("end") #结果: say hi 0 say hi 1 end

进程(锁)

进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题,竞争带来的结果就是错乱,如何控制,就是加锁处理 import multiprocessing import sys def worker_with(lock, f): with lock: # #with Lock的作用相当于自动获取和释放锁(资源) fs = open(f, 'a+') n = 10 while n > 1: fs.write("Lockd acquired via with\n") n -= 1 fs.close() ''' with lock 和 lock.acquire()与lock.release()等价的 ''' def worker_no_with(lock, f): lock.acquire() try: fs = open(f, 'a+') n = 10 while n > 1: fs.write("Lock acquired directly\n") n -= 1 fs.close() finally: lock.release() if __name__ == "__main__": lock = multiprocessing.Lock() f = "file.txt" w = multiprocessing.Process(target=worker_with, args=(lock, f)) nw = multiprocessing.Process(target=worker_no_with, args=(lock, f)) w.start() nw.start() print("end")

进程池:

#一:使用进程池(非阻塞,apply_async) #coding: utf-8 from multiprocessing import Process,Pool import time def func(msg): print( "msg:", msg) time.sleep(1) return msg if __name__ == "__main__": pool = Pool(processes = 3) res_l=[] for i in range(10): msg = "hello %d" %(i) res=pool.apply_async(func, (msg, )) #维持执行的进程总数为processes,当一个进程执行完毕后会添加新的进程进去 res_l.append(res) print("==============================>") #没有后面的join,或get,则程序整体结束,进程池中的任务还没来得及全部执行完也都跟着主进程一起结束了 pool.close() #关闭进程池,防止进一步操作。如果所有操作持续挂起,它们将在工作进程终止前完成 pool.join() #调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束 print(res_l) #看到的是<multiprocessing.pool.ApplyResult object at 0x10357c4e0>对象组成的列表,而非最终的结果,但这一步是在join后执行的,证明结果已经计算完毕,剩下的事情就是调用每个对象下的get方法去获取结果 for i in res_l: print(i.get()) #使用get来获取apply_aync的结果,如果是apply,则没有get方法,因为apply是同步执行,立刻获取结果,也根本无需get #二:使用进程池(阻塞,apply) #coding: utf-8 from multiprocessing import Process,Pool import time def func(msg): print( "msg:", msg) time.sleep(0.1) return msg if __name__ == "__main__": pool = Pool(processes = 3) res_l=[] for i in range(10): msg = "hello %d" %(i) res=pool.apply(func, (msg, )) #维持执行的进程总数为processes,当一个进程执行完毕后会添加新的进程进去 res_l.append(res) #同步执行,即执行完一个拿到结果,再去执行另外一个 print("==============================>") pool.close() pool.join() #调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束 print(res_l) #看到的就是最终的结果组成的列表 for i in res_l: #apply是同步的,所以直接得到结果,没有get()方法 print(i) 详解:apply_async与apply 详解:apply_async与apply

 


最新回复(0)