分布式的开发现在应该是炙手可热。消息队列是实现分布式的一个方法。
Queue的整个使用过程
管理进程:
1) 创建队列,声明队列中的元素个数
2) 定义队列的回调函数
3) 注册队列的回调函数方法
4) 为QueueManager绑定地址及端口,设置authkey
5) 获取队列,入队与出队
任务进程:
1) 注册用于获取queue的方法名称,任务进程只能通过名称获取在网络上获取Queue
2) 根据ip,端口,authkey来连接服务器
在windows中的代码如下:
taskManager.py
from queue import Queue
from multiprocessing.managers import BaseManager
from multiprocessing import freeze_support
task_number = 10
task_queue = Queue(task_number)
result_queue = Queue(task_number)
def get_task():
return task_queue
def get_result():
return result_queue
class QueueManager(BaseManager):
pass
def win_run():
QueueManager.register('get_task_queue',callable = get_task)
QueueManager.register('get_result_queue',callable=get_result)
manager = QueueManager(address=('127.0.0.1',8001),authkey=b'abc')
manager.start()
try:
task = manager.get_task_queue()
result = manager.get_result_queue()
for url in ['ImageUrl_'+str(i) for i in range(10)]:
print('put task %s ...'%url)
task.put(url)
print('try get result...')
for i in range(10):
print('result is %s'% result.get(timeout=10))
except:
print('Manager error')
finally:
manager.shutdown()
if __name__ == '__main__':
freeze_support()
win_run()
taskWorker.py
import time
from multiprocessing.managers import BaseManager
class QueueManager(BaseManager):
pass
QueueManager.register('get_task_queue')
QueueManager.register('get_result_queue')
server_addr='127.0.0.1'
print('Connect to server %s...' % server_addr)
m=QueueManager(address=(server_addr,8001),authkey=b'abc')
m.connect()
task=m.get_task_queue()
result=m.get_result_queue()
while(not task.empty()):
image_url = task.get(True,timeout=5)
print('run task download %s...'%image_url)
time.sleep(1)
result.put('%s---->success'%image_url)
print('worker exit.')
程序运行结果为:
注意点:
在创建QueueManager中如果authkey之后没有加入b
报错如下:
那么也许,我们先要了解下在Python中字符串前面b的意义
在python中,字符串前面可能会出现:
1. U 后面为中文组成的字符串
2. R 后面为普通字符串,主要如转义字符等问题,用在正则表达式,文件绝对地址中
3. B python3 中默认的str为unicode,b代表为bytes,是python2中的str
所以,在报错中,也看到提示没有encoding的提示
知识点:
1.freeze_support作用:
百度中没有看到,直接到官网中去查看:
Add support for when a program which uses multiprocessing has been frozen to produce a Windows executable. (Has been tested with py2exe, PyInstaller and cx_Freeze.)
One needs to call this function straight after the if __name__ == '__main__' line of the main module. For example:
from multiprocessing import Process, freeze_support
def f():
print 'hello world!'
if __name__ == '__main__':
freeze_support()
Process(target=f).start()
If the freeze_support() line is omitted then trying to run the frozen executable will raise RuntimeError.
Calling freeze_support() has no effect when invoked on any operating system other than Windows. In addition, if the module is being run normally by the Python interpreter on Windows (the program has not been frozen), then freeze_support() has no effect.
来自 https://docs.python.org/2/library/multiprocessing.html
翻译:
1)在windows下的多进程模式使用,如果Python解释器已经正确的运行在windows中,该函数将没有作用。
2)需要在main函数后面直接调用
2.pass作用
在python中pass是空语句,只是为了保持程序结构的完整性。