【发布时间】:2013-02-12 19:46:42
【问题描述】:
我正在编写一个家庭自动化助手——它们基本上是类似守护进程的小型 Python 应用程序。他们可以将每个进程作为一个单独的进程运行,但既然会这样,我决定我将建立一个小型调度程序,它将在它们自己的线程中生成每个守护进程,并且能够在将来线程死亡时采取行动。
这就是它的样子(使用两个类):
from daemons import mosquitto_daemon, gtalk_daemon
from threading import Thread
print('Starting daemons')
mq_client = mosquitto_daemon.Client()
gt_client = gtalk_daemon.Client()
print('Starting MQ')
mq = Thread(target=mq_client.run)
mq.start()
print('Starting GT')
gt = Thread(target=gt_client.run)
gt.start()
while mq.isAlive() and gt.isAlive():
pass
print('something died')
问题是 MQ 守护进程 (moquitto) 可以正常工作,我是否应该直接运行它:
mq_client = mosquitto_daemon.Client()
mq_client.run()
它将启动并挂在那里收听所有涉及相关主题的消息 - 正是我正在寻找的。p>
但是,在调度程序中运行会使其行为怪异 - 它会收到一条消息然后停止执行,但报告线程仍处于活动状态。鉴于它在没有线程woodoo 的情况下工作正常,我假设我在调度程序中做错了什么。
我引用 MQ 客户端代码以防万一:
import mosquitto
import config
import sys
import logging
class Client():
mc = None
def __init__(self):
logging.basicConfig(format=u'%(filename)s:%(lineno)d %(levelname)-8s [%(asctime)s] %(message)s', level=logging.DEBUG)
logging.debug('Class initialization...')
if not Client.mc:
logging.info('Creating an instance of MQ client...')
try:
Client.mc = mosquitto.Mosquitto(config.DEVICE_NAME)
Client.mc.connect(host=config.MQ_BROKER_ADDRESS)
logging.debug('Successfully created MQ client...')
logging.debug('Subscribing to topics...')
for topic in config.MQ_TOPICS:
result, some_number = Client.mc.subscribe(topic, 0)
if result == 0:
logging.debug('Subscription to topic "%s" successful' % topic)
else:
logging.error('Failed to subscribe to topic "%s": %s' % (topic, result))
logging.debug('Settings up callbacks...')
self.mc.on_message = self.on_message
logging.info('Finished initialization')
except Exception as e:
logging.critical('Failed to complete creating MQ client: %s' % e.message)
self.mc = None
else:
logging.critical('Instance of MQ Client exists - passing...')
sys.exit(status=1)
def run(self):
self.mc.loop_forever()
def on_message(self, mosq, obj, msg):
print('meesage!!111')
logging.info('Message received on topic %s: %s' % (msg.topic, msg.payload))
【问题讨论】:
-
此外,如果您在每个进程中生成多个实例(
Client.mc与self.mc和mc = None,则将mc设置为类属性而不是实例属性可能会导致其他问题只是在__init__阶段设置self.mc,)取决于蚊子客户端在多个实例中的行为。
标签: python multithreading mq