多进程
如果你打算编写多进程的服务程序,Unix/Linux无疑是正确的选择。由于Windows没有fork调用,难道在Windows上无法用Python编写多进程的程序?
由于Python是跨平台的,自然也应该提供一个跨平台的多进程支持。multiprocessing模块就是跨平台版本的多进程模块。
multiprocessing模块提供了一个Process类来代表一个进程对象
multiprocessing
import multiprocessing
import os
def info(title):
print(title)
print(__name__)
print('father', os.getppid())
print('self', os.getpid())
print('--------')
if __name__ == "__main__": # 除了创建的子进程和子进程调用函数,其他的都是脚本主进程
# info('hello')
# 创建一个子进程调用函数
P = multiprocessing.Process(target=info,args=('hello python',))
P.start()
P.join() # 和多线程一样,也是等待的意思
print('hello word') # 若没有join则会独立运行
=====================================
__mp_main__
father 8768
self 6980
--------
hello word
创建子进程时,只需要传入一个执行函数和函数的参数,创建一个Process实例,用start()方法启动,这样创建进程比fork()还要简单。
join()方法可以等待子进程结束后再继续往下运行,通常用于进程间的同步。
进程间通信
Process之间肯定是需要通信的,操作系统提供了很多机制来实现进程间的通信。Python的multiprocessing模块包装了底层的机制,提供了Queue、Pipes等多种方式来交换数据。
Pipes(管道)
# 进程通信
import multiprocessing
import os
def func(conn): # conn表示管道类型
print('func',os.getpid(), conn.recv()) # 收到的数据
conn.send(['a', 'b', 'c', 'd', 'e']) # 发送的数据
conn.close() # 关闭
if __name__ == "__main__":
conn_a, conn_b = multiprocessing.Pipe() # 创建一个管道,有两个口
# print(id(conn_a),id(conn_b))
# print(type(conn_a), type(conn_b)) #multiprocessing.connection.Connection链接,意思就是连接口
# 相当于在进程中conn_a.send(['a','b','c','d','e']),发送给conn_b
p = multiprocessing.Process(target=func, args=(conn_a,)).start()
conn_b.send([1, 2, 3, 4, 5, 6, 7]) # 发送数据给conn_a
print('mian',os.getpid(), conn_b.recv())
=======================================
func 8800 [1, 2, 3, 4, 5, 6, 7]
mian 7868 ['a', 'b', 'c', 'd', 'e']
Queue(列表)
# 队列可以进程共享
import multiprocessing
import os
queue = multiprocessing.Queue()
# 注意队列只能单向,要么是父进程插入子进程取出,要么是子进程插入父进程取出
def func(myq):
print(os.getpid())
myq.put([1, 2, 3, 4]) # 子进程插入
if __name__ == '__main__':
print(os.getpid())
# queue.put(['a','b']) # 这里若是脚本父进程先插入了,子进程就没法再插入了
p = multiprocessing.Process(target=func, args=(queue,))
p.start()
print(queue.get()) # 脚本父进程取出
=========================
4300
6316
[1, 2, 3, 4]
实例机器人:
import os
import multiprocessing
def M(conn):
while 1:
recv_ =conn.recv()
print('机器人收到:%s'%recv_)
if recv_ == "你好":
conn.send('我不好~')
elif recv_ == "我帅吗":
conn.send('你是最帅的!呕!!!!')
elif recv_ == "老子吃火锅 你吃火锅底料":
conn.send('老子坐火车,你坐火车轨道;老子娶天仙,你娶天线宝宝;老子吹空调,你吹空调外机;老子吃西瓜,你吃西瓜皮皮;老子吃泡面,你吃调味料包;老子吃风爪,你吃陈年泡椒;老子吃酸奶,你舔奶瓶盖盖;老子吃辣条,你舔塑料袋袋。')
elif recv_ == "工资多少":
conn.send('都用来充电费了')
else:
conn.send('SB!滚!别来烦大爷')
def P(conn):
y = 'y'
while y != 'n':
input_ = input('人说:')
conn.send(input_)
print(conn.recv())
if __name__ == "__main__":
conn_M,conn_P = multiprocessing.Pipe()
p_M=multiprocessing.Process(target = M, args = (conn_M,))
p_M.start()
P(conn_P)
===========================
人说:工资多少
机器人收到:工资多少
都用来充电费了
人说:等等
机器人收到:等等
SB!滚!别来烦大爷