本篇博客主要写进程锁,__name__ == "__main__"函数作用,以及进程池的使用。
二、进程同步
2.1、进程锁
说明:通过multiprocessing中的Lock模块来实现进程锁。
from multiprocessing import Process,Lock #导入进程锁 def f(l,i): l.acquire() #加锁 try: print("hello word",i) finally: l.release() #释放锁 if __name__ == "__main__": lock = Lock() #定义锁 for num in range(10): Process(target=f,args=(lock,num,)).start() #把锁传入进程中1、这边不禁的有个疑问,就是进程中不是相互独立的吗?为啥还要加锁呐?
虽然每个进程都是独立运行的,但是问题来了,它们共享一块屏幕。这个锁存在的意义就是屏幕共享。如果也想抱着打印数据,而我想也想打印数据的情况,就有可能乱套了,然后通过这个锁来控制,去打印的时候,这个屏幕只有我独占,导致屏幕不会乱。
2、代码中的__name__ == "__main__"是干嘛用的?
它的作用是为了区分你是主动执行这个脚本还是从别的地方把它当做一个模块去调用。如果主动执行这个脚本,那么__name__ == "__main__" 以下的代码就会执行,如果其他模块导入的,则在其他模块中不执行__name__ == "__main__"以下的代码。这边一般在一个模块中测试用的,但是其他模块又不能执行这部分代码。
三、进程池
进程池的作用:防止启动太多的进程把系统干趴下,才有了进程池的限制,比如说,你起了100个进程,会变慢,起一个进程相当于克隆一个父进程,父进程占1G内存空间,100个进程就占101G的内存,所以进程池就是在同一时间允许多个进程在cpu上运行。
说明:这个说明是同步执行的,也就是串行执行的
from multiprocessing import Pool #导入进程池模块pool import time,os def Foo(i): time.sleep(2) print("in process",os.getpid()) #打印进程号 return i+100 if __name__ == "__main__": pool = Pool(processes=5) #设置进程池个数为5,也可以写成pool = Pool(5),允许进程池同时放入5个进程,并且这5个进程交给cpu去运行 for i in range(10): pool.apply(func=Foo, args=(i,)) #同步执行挂起进程 print('end') pool.close() pool.join()#进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。注:这边的5个进程只是挂起了,并没有真正的去执行,但是执行的时候,只能执行这个5个进程。这个apply是同步的,也就是串行的,一般不用。
说明:异步执行,也就是并行执行。
from multiprocessing import Pool #导入进程池模块 import time,os def Foo(i): time.sleep(2) print("in process",os.getpid()) return i+100 if __name__ == "__main__": pool = Pool(processes=5) #定义进程池 for i in range(10): pool.apply_async(func=Foo, args=(i,)) #采用异步的方式,加进程池 print('end') pool.close() pool.join()#进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。注:最后的pool.join()不能省略,不然的话,这个pool的进程池就直接关闭了, 它不会等待执行的结果的。
说明:在计算机中,这个程序执行完毕之后,再回调过来执行这个Bar。
from multiprocessing import Process,Pool import time,os def Foo(i): time.sleep(2) print("in process",os.getpid()) #打印子进程的进程号 return i+100 def Bar(arg): print('-->exec done:',arg,os.getpid()) #打印进程号 if __name__ == "__main__": pool = Pool(processes=2) print("主进程",os.getpid()) #主进程的进程号 for i in range(3): pool.apply_async(func=Foo, args=(i,),callback=Bar) #执行回调函数callback=Bar print('end') pool.close() pool.join()#进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。 #输出 主进程 4296 end in process 48604 in process 46280 -->exec done: 101 4296 -->exec done: 100 4296 in process 48604 -->exec done: 102 4296说明:
回调函数说明fun=Foo干不完就不执行bar函数,等Foo执行完就去执行Bar这个回调函数是主进程去调用的,而不是每个子进程去调用的。回调函数的用处:
比如说你从各个机器上备份完毕,在回调函数中自动写一个脚本,说备份完毕。
回调函数是主进程调用的原因?
如果是子进程去调用这个回调函数,有多少个子进程就有多少个连接,如果是主进程的话,只需要一次长连接就可以了,这个效率就高了。
转载于:https://www.cnblogs.com/xiangjun555/articles/7735385.html