我试图在一个线程中捕获异常并在主线程中重新引发它:
import threading
import sys
class FailingThread(threading.Thread):
def run(self):
try:
raise ValueError('x')
except ValueError:
self.exc_info = sys.exc_info()
failingThread = FailingThread()
failingThread.start()
failingThread.join()
print failingThread.exc_info
raise failingThread.exc_info[1]
Run Code Online (Sandbox Code Playgroud)
这基本上起作用并产生以下输出:
(<type 'exceptions.ValueError'>, ValueError('x',), <traceback object at 0x1004cc320>)
Traceback (most recent call last):
File "test.py", line 16, in <module>
raise failingThread.exc_info[1]
Run Code Online (Sandbox Code Playgroud)
但是,异常的来源指向第16行,其中发生了重新加注.原始异常来自第7行.如何修改主线程以使输出显示:
Traceback (most recent call last):
File "test.py", line 7, in <module>
Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个看似简单的经典生产者实现 - Python中的消费者习语.对于多个较慢的消费者,有一个相对较快的生产者.原则上,使用Queue模块很容易做到这一点,而库文档只有几行代码.
但是,我还希望代码在异常发生时正常工作.如果发生以下任何事情,生产者和所有消费者都应该停止:
在此之后,整个过程应该无法提出初始异常,以通知调用者出错的地方.
主要的挑战似乎是干净地终止消费者线程,而不是最终阻塞join().设置Thread.deamon = True似乎很流行,但据我所知,如果生产者因异常而失败,这会导致资源泄漏.
我设法编写了一个满足我要求的实现(见下文).但是我发现代码比预期的要复杂得多.
是否有更精简的方式来处理这些情况?
以下是一些示例调用以及来自当前实现的最终日志消息:
生产和消费10件物品:
$ python procon.py
INFO:root:processed all items
Run Code Online (Sandbox Code Playgroud)
不产生任何物品:
$ python procon.py --items 0
INFO:root:processed all items
Run Code Online (Sandbox Code Playgroud)
为10个消费者生产5个项目,因此仅使用一些可用的消费者:
$ python procon.py --items 5 --consumers 10
INFO:root:processed all items
Run Code Online (Sandbox Code Playgroud)
按Control-C中断:
$ python procon.py
^CWARNING:root:interrupted by user
Run Code Online (Sandbox Code Playgroud)
未能生产第3项:
$ python procon.py --producer-fails-at 3
ERROR:root:cannot produce item 3
Run Code Online (Sandbox Code Playgroud)
无法使用第3项:
$ python procon.py --consumer-fails-at 3
ERROR:root:cannot consume item 3
Run Code Online (Sandbox Code Playgroud)
无法使用最后一项:
$ python procon.py --items 10 --consumer-fails-at 9
ERROR:root:cannot consume …Run Code Online (Sandbox Code Playgroud) 是否有一种简洁且内存有效的方法来找出两个迭代器是否lines1产生lines2相同的项目?
例如,这些迭代器可以是从文件对象检索的行:
with io.open(`some.txt`, 'r', encoding='...') as lines1:
with io.open(`other.txt`, 'r', encoding='...') as lines2:
lines_are_equal = ...
Run Code Online (Sandbox Code Playgroud)
直觉上人们可以预期
lines_are_equal = lines1 == lines2 # DOES NOT WORK
Run Code Online (Sandbox Code Playgroud)
会给出想要的结果。然而,这始终是False因为它只比较迭代器的地址而不是产生的项目。
如果内存不是问题,可以将迭代器转换为列表并比较它们:
lines_are_equal = list(lines1) == list(lines2) # works but uses a lot of memory
Run Code Online (Sandbox Code Playgroud)
我已经检查过itertools,希望找到类似的东西
lines_are_equal = itertools.equal(lines1, lines2) # DOES NOT WORK
Run Code Online (Sandbox Code Playgroud)
但好像没有这样的功能。
到目前为止我能想到的最好的方法是使用itertools.zip_longest()(Python 2:)循环两个迭代器izip_longest():
lines_are_equal = True
for line1, line2 in itertools.zip_longest(lines1, lines2):
if line1 != line2:
lines_are_equal …Run Code Online (Sandbox Code Playgroud) 如果多个持久订阅者尝试使用相同的客户端 ID 进行连接,我如何告诉 mosquitto MQTT 该怎么做?
在错误配置订阅同一个代理的不同测试环境时,我不小心遇到了这种情况。结果是,两个订阅者都只收到了部分消息,并且 mosquitto 日志中充斥着“来自 xxx 的新连接”消息的垃圾邮件。优选地,第二订户将被拒绝以立即使这种错误显而易见。
我为 Solace找到了一个类似的问题,它似乎提供了用新订阅者替换旧订阅者或拒绝新订阅者的选项。
但是,在检查mosquitto.conf的可用选项时,我看不到类似的选项。
python ×3
compare ×1
exception ×1
iterator ×1
mosquitto ×1
mqtt ×1
python-2.7 ×1
queue ×1
stack-trace ×1