由于GIL的原因,Python不支持真正意义上的多线程于是转而求其次,Python使用多进程来完成并行任务。
Python的multiprocessing库就是多进程的利器, 它能够像多现成一样的使用多进程,注意 python version 2.6+ 能够简单快捷的进行多任务开发。 多进程间共享数据,可以使用 multiprocessing.Value 和 multiprocessing.Array 等 下面这里介绍一下共享数据的方式
交换对象
Queues
frommultiprocessing importProcess, Queue
deff(q):
q.put([42,None,'hello'])
if__name__ =='__main__':
q=Queue()
p=Process(target=f, args=(q,))
p.start()
printq.get()
# prints "[42, None, 'hello']"
p.join()
Pipes
frommultiprocessing importProcess, Pipe
deff(conn):
conn.send([42,None,'hello'])
conn.close()
if__name__ =='__main__':
parent_conn, child_conn =Pipe()
p=Process(target=f, args=(child_conn,))
p.start()
printparent_conn.recv()
# prints "[42, None, 'hello']"
p.join()
数据共享
共享内存
frommultiprocessing importProcess, Value, Array
deff(n, a):
n.value=3.1415927
fori inrange(len(a)):
a[i]=-a[i]
if__name__ =='__main__':
num=Value('d',0.0)
arr=Array('i',range(10))
p=Process(target=f, args=(num, arr))
p.start()
p.join()
printnum.value
printarr[:]
具体参数含义,看这里
Server process
frommultiprocessing importProcess, Manager
deff(d, l):
d[1]='1'
d['2']=2
d[0.25]=None
l.reverse()
if__name__ =='__main__':
manager=Manager()
d=manager.dict()
l=manager.list(range(10))
p=Process(target=f, args=(d, l))
p.start()
p.join()
printd
printl
结合多进程SocketServer,和数据共享,写一个测试代码
服务器端
#!/usr/bin/env python
# -*- coding: UTF8 -*-
importtime
importthreading
importthread
importSocketServer
frommultiprocessing importManager
classAppHandler(SocketServer.BaseRequestHandler):
def__init__(self, request, client_address, server):
SocketServer.BaseRequestHandler.__init__(self, request, client_address, server)
defsetup(self):
print("%s is connected!" % self.client_address[0])
yes=Application.yes
yes[self.client_address[0]]=self.client_address[0]
self.test=yes[self.client_address[0]]
defhandle(self):
whileTrue:
try:
recv=self.request.recv(6)
printself.test
printrecv[2]
# if clinet close this is a Exception and goto Exception
exceptException, e:
print(e)
self.request.send("error")
break
deffinish(self):
yes=Application.yes
yes[self.client_address[0]]=None
print("%s disconnected." % self.client_address[0])
classAppServer(SocketServer.ForkingTCPServer):
"""
App level TCP server with connection management.
"""
stopped=False
allow_reuse_address=True
def__init__(self, server_address, RequestHandlerClass):
print"server start init"
SocketServer.ForkingTCPServer.__init__(self, server_address, RequestHandlerClass)
defserve_forver(self):
whilenot self.stopped:
self.handle_request()
defstop(self):
self.stopped=True
self.shutdown()
self.socket.close()
defverify_request(self, request, client_address):
returnTrue
defclose_request(self, request):
print("%d"% thread.get_ident())
classApplication():
thread=None
server=None
manager=None
yes=None
def__init__(self, ip, port):
self.port=port
self.ip=ip
defstartup(self):
print("Application startup ...")
try:
Application.manager=Manager()
Application.yes=Application.manager.dict()
Application.server=AppServer((self.ip,self.port), AppHandler)
Application.thread=threading.Thread(name="Application server", target=Application.server.serve_forever)
Application.thread.start()
exceptException, e:
print(e)
finally:
whileTrue:
print"while"
printApplication.yes
time.sleep(3)
defshutdown(self):
print("Application shutdown ...")
try:
Application.server.stop()
exceptException, e:
print(e)
time.sleep(1)
if__name__ =="__main__":
ip="192.168.100.160"
port=6002
app=Application(ip, port)
app.startup()
客户端
#!/usr/bin/env python
# -*- coding: UTF8 -*-
importsocket
importtime
importsys
selfip="192.168.100.4"
iflen(sys.argv) >=2:
selfip=sys.argv[1]
HOST='192.168.100.160'
# The remote host
PORT=6002
# The same port as used by the server
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((selfip,5678))
s.connect((HOST, PORT))
whileTrue:
s.send('world!')
#data = s.recv(1024)
#print 'Received', repr(data)
time.sleep(1)
s.close()
转载自:http://zhblog.github.io/blog/2012/09/18/python-multiprocessing.html