multiprocessing is a package that supports spawning processes using an API similar to the threading module. The multiprocessing package offers both local and remote concurrency, effectively sIDe-stepPing the Global Interpreter Lock by using subprocesses instead of threads. Due to this, the multiprocessing module allows the programmer to fully Leverage multiple processors on a given machine. It runs on both Unix and windows.
这个模块的语法结构与threading模块基本相似。
查找到一个多进程的博客连接:https://www.cnblogs.com/Mr-Murray/p/9026955.html
from multiprocessing import Processimport timeimport osdef info(): print("3[35;1mThe time is %s3[0m" % time.ctime()) print("The parent is %s; The Child process is %s" % (os.getppID(), os.getpID()))if __name__ == "__main__": for i in range(10): p = Process(target=info) p.start() p.join()
这段代码和之前用threading模块创建的多线程并没有任何的区别,但是如果在windows系统上执行时,必须加上if __name__ == "__main__":语句,原因如下:
在windows *** 作系统中由于没有fork(linux *** 作系统中创建进程的机制),在创建子进程的时候会自动 import 启动它的这个文件,而在 import 的时候又执行了整个文件。因此如果将process()直接写在文件中就会无限递归创建子进程报错。所以必须把创建子进程的部分使用if __name__ ==‘__main__’ 判断保护起来,import 的时候 ,就不会递归运行了。以实例化的方式产生进程:
import os, timefrom multiprocessing import Processclass Myprocess(Process): def __init__(self): super(Myprocess, self).__init__() def run(self): print("3[35;1mThe time is %s3[0m" % time.ctime()) print("The parent is %s; The Child process is %s" % (os.getppID(), os.getpID()))if __name__ == "__main__": p = Myprocess() p.start()#在调用p.start的时候,会自动执行类中的run方法,run方法是必不可少的。和threading类中的Thread中的run方法一样。
进程中的守护进程和threading模块中的守护线程是同一个意思,主进程结束的时候,子进程也会随之结束。
import os, timefrom multiprocessing import Processdef fun1(): print("starting %s".center(50,"-") % time.ctime()) time.sleep(3) print("StopPing %s".center(50,"-") % time.ctime())if __name__ == "__main__": p = Process(target=fun1) p.daemon = True p.start() time.sleep(1)--------------------------------------------------------------------------子进程中是要执行3s的,但主进程中只执行了1s,设置了守护进程之后,主进程结束,不管子进程的状态,子进程都要退出
利用多进程实现简易的socket并发连接。
server端代码:import socket, timefrom multiprocessing import Processdef handle(conn,addr): print("The connection is from %s at %s port" % addr) conn.send(b"Hello world") data = conn.recv(1024) conn.send(data)if __name__ == "__main__": HOST = "localhost" PORT = 51423 ADDR = (HOST, PORT) s = socket.socket(socket.AF_INET, socket.soCK_STREAM) s.bind(ADDR) s.Listen(5) while True: conn, addr = s.accept() p = Process(target=handle, args=(conn,addr)) # 进程间的数据是不共享的,因此需要把coon作为参数传递 p.start() s.close()clIEnt端代码:import socketHOST = "localhost"PORT = 51423ADDR = (HOST, PORT)s = socket.socket(socket.AF_INET, socket.soCK_STREAM)s.connect(ADDR)data = s.recv(1024)print(data.decode())while True: info = input(">>>: ") s.send(info.encode()) data = s.recv(1024) print(data.decode())
注意:
进程之间的数据是彼此之间不能互相访问的,因此conn必须作为参数传递。
进程之间的通信该怎么做?
进程中的队列和管道:from multiprocessing import Process, Queuefrom time import sleepimport random# 利用进程写一个生成消费者模型,# 生成者向队列插入一个随机数,消费者取出队列中的一个数值def productor(q): while True: sleep(0.3) print("store an num") q.put(random.randint(1,100))def consumer(q): while True: sleep(0.2) print("Getting an num") q.get()if __name__ == "__main__": q = Queue() proc1 = Process(target=productor, args=(q,)) proc2 = Process(target=consumer, args=(q,)) proc1.start() proc2.start()
这只是一个简易模型,来说明队列在进程之间的通信。
这里的队列用法和线程中队列用法基本相同,只是一个用于进程通信,一个用于线程通信。
管道
管道的简单实用:
from multiprocessing import Process, Pipedef f(conn): conn.send("Hello world") conn.close()if __name__ == '__main__': parent_conn, child_conn = Pipe() p = Process(target=f, args=(child_conn,)) p.start() print(parent_conn.recv()) p.join()manager
Manager()返回的manager对象控制了一个server进程,此进程包含的python对象可以被其他的进程通过proxIEs来访问。从而达到多进程间数据通信且安全。
A manager object returned by Manager() controls a server process which holds Python objects and allows other processes to manipulate them using proxIEs.
A manager returned by Manager() will support types list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, @L_404_13@, Event, Barrier, Queue, Value and Array.
一个简单实用的实例:
from multiprocessing import Process, Managerimport randomdef f(List): List.append(random.randint(0,100)) print(List)if __name__ == "__main__": p_List = [] with Manager() as manager: l = manager.List() for i in range(10): p = Process(target=f,args=(l,)) p.start() p_List.append(p) for res in p_List: res.join()
每一个进程给列表中添加一个数据,执行结果如下:
[95]
[95, 25]
[95, 25, 31]
[95, 25, 31, 70]
[95, 25, 31, 70, 9]
[95, 25, 31, 70, 9, 17]
[95, 25, 31, 70, 9, 17, 96]
[95, 25, 31, 70, 9, 17, 96, 71]
[95, 25, 31, 70, 9, 17, 96, 71, 96]
[95, 25, 31, 70, 9, 17, 96, 71, 96, 3]
进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。
from multiprocessing import Process, Poolimport timedef Foo(i): time.sleep(2) return i + 100def bar(arg): print('-->exec done:', arg)if __name__ == "__main__": pool = Pool(5) for i in range(10): pool.apply_async(func=Foo, args=(i,), callback=bar) # pool.apply(func=Foo, args=(i,)) print('end') pool.close() pool.join()
注意:其中在调用apply_async时候使用了callback回调函数
总结
以上是内存溢出为你收集整理的python进程编程全部内容,希望文章能够帮你解决python进程编程所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)