作为该领域的新手,我一直在尝试使用线程解决GIL限制,以便为我的自定义Slack机器人(用python编写)处理多个传入的RTM事件
用例: 一个Slack Bot,它将被添加到几个通道,必须同时服务多个请求(机器人命令) 。
面临的挑战 由于python中的Threading遵循GIL的概念,因此传入的bot请求实际上不是 并行执行的。
解决方案进行了调查: 作为替代方案,我正在研究multiprocessing.pool,它将使我产生许多可以互斥的方式满足每个请求的工作程序。
问题:由于我在同时循环中无限地轮询传入的事件,因此我需要找到一种方法来生成进程响应每个传入请求,而不会阻塞另一个请求的处理(可以在相同时间从另一个渠道发布)而不会耗尽所有可用内存。< / p>
代码: 当我将此漫游器订阅到单个频道,并且有多个命令发布时,这种方法可以正常工作。问题是当存在多个参与者/通道的多通道时,响应时间会很长。 是否可以采用任何方法/编程范例来解决此问题? slack_client = SlackClient(<bot_token>)
if slack_client.rtm_connect(auto_reconnect=True):
while True:
incoming_events = slack_client.rtm_read()
command = parse_bot_mention(incoming_events) #this method returns the command issued to the bot in specific
if command:
handle_command_thread = Thread(target=handle_bot_command, args=(command))
handle_command_thread.start()
time.sleep(1) #RTM read delay of 1 sec
答案 0 :(得分:0)
似乎您在处理并发性时遇到了Python的弱点之一。杜德,那真是痛苦!我将把您的一些想法限制在您的问题范围内,但不要在我犯下我的最大 StackOverflow宠物烦恼之前...通过告诉您完全尝试其他方法来回答您的问题...
烦人的答案:您正在描述的用例似乎需要一个使并发成为一等公民的工具,这就是为什么我建议您考虑使用Golang的原因。来自非常沉重的Python背景,我发现拿起Golang并不是很困难。 Golang使用“例程”轻松处理类似您遇到的问题。它还具有许多您应该签出的其他非常好的功能(例如键入..哦,是的!)。如果您习惯了Python Dev的工作,乍一看有点奇怪,但是在您掌握了概念之后,这相当简单!
不烦人的答案:好的,如果您阅读以上内容,我会很感激,让我在您的问题范围内提出一些想法。
因此,您将创建一个函数,将类似
的内容插入while循环中Def Dispatch_worker_boi(self, command):
use multiprocessing function to pitch to a worker (see Pool.apply_async)
最后的注释: Chiragjn列出的另一种方法是使用某种类型的排队服务,例如芹菜。这将使您能够坚持使用Python,并且比纯Python方法具有更多的可伸缩性。不过,老实说,如果您要处理的规模很大,Golang将为您提供良好的服务。
希望这对您有所帮助,请随时提供反馈!