记录py3学习过程中的两个小坑
环境:
1. Windows7 x64,Python 3.4.3 64/32 bit
2. Linux Mint 17.1 x64,Python 3.4.0
1 进程
环境1中,进程的join方法似乎没有得到预期的效果:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from multiprocessing import Process
import os,time
def run_proc(name):
print ('Run child process %s (%s)……'%(name,os.getpid()))
if __name__=='__main__':
print ('Parent process %s.'%(os.getpid()))
p=Process(target=run_proc,args=('test100',))
print ('Process will start (child).')
p.start()
p.join()
print ('Process end (child).')
print ('**********123****************')
print ('456')
输出:
Q1 为何中间会多出一个456
的输出?
同样的代码在环境2中输出符合预期:
2 分布式进程
按照廖雪峰的py教程写的代码,教程用py2,这里是py3.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# taskmanager.py
import random, time
import queue
from multiprocessing.managers import BaseManager
# 发送任务的队列:
task_queue = queue.Queue()
# 接收结果的队列:
result_queue = queue.Queue()
# 从BaseManager继承的QueueManager:
class QueueManager(BaseManager):
pass
# 把两个Queue都注册到网络上, callable参数关联了Queue对象:
QueueManager.register('get_task_queue', callable=lambda: task_queue)
QueueManager.register('get_result_queue', callable=lambda: result_queue)
# 绑定端口5000, 设置验证码'1qaz':
manager = QueueManager(address=('', 5000), authkey=('1qaz'.encode('UTF-8')))
# 启动Queue:
manager.start()
# 获得通过网络访问的Queue对象:
task = manager.get_task_queue()
result = manager.get_result_queue()
# 放几个任务进去:
for i in range(10):
n = random.randint(0, 10000)
print('Put task %d...' % (n))
task.put(n)
# 从result队列读取结果:
print('Try get results...')
for i in range(10):
r = result.get(timeout=12)
print('Result: %s' % r)
# 关闭:
manager.shutdown()
远程代码:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# taskworker.py
import time, sys, queue
from multiprocessing.managers import BaseManager
# 创建类似的QueueManager:
class QueueManager(BaseManager):
pass
# 由于这个QueueManager只从网络上获取Queue, 所以注册时只提供名字:
QueueManager.register('get_task_queue')
QueueManager.register('get_result_queue')
# 连接到服务器, 也就是运行taskmanager.py的机器:
server_addr = '127.0.0.1'
print('Connect to server %s...' % server_addr)
# 端口和验证码注意保持与taskmanager.py设置的完全一致:
m = QueueManager(address=(server_addr, 5000), authkey='1qaz'.encode('UTF-8'))
# 从网络连接:
m.connect()
# 获取Queue的对象:
task = m.get_task_queue()
result = m.get_result_queue()
# 从task队列取任务,并把结果写入result队列:
for i in range(10):
try:
n = task.get(timeout=1)
print('run task %d * %d...' % (n, n))
r = '%d * %d = %d' % (n, n, n*n)
time.sleep(1)
result.put(r)
except Queue.Empty:
print('task queue is empty.')
# 处理结束:
print('worker exit.')
Q2 在环境1中即使使用管理员用户, 也会出现OSError: [WinError 87] 参数错误。
或者PermissionError: [WinError 5] 拒绝访问。
。
环境2中,正常:
以上两个问题,暂时没有深入研究, 估计是编译器在处理进程的时候还有待完善。先记录在此,后来人能看到这,就直接跳过去了。
PS: Py3中import Queue
应为import queue
;
authkey='abc'
需要编码, 如authkey='1qaz'.encode('utf-8')
, 同样在taskworker.py
中也需要编码。
CSDN终于支持Markdown了。。。。。。。。