多个相互通信的线程

时间:2017-05-22 14:42:08

标签: python

我试图在Python 2.7中做一些事情,但我无法弄明白。 我想要的是同时执行两组操作,另外还需要两个线程相互通信。

更具体地说:我想发送一系列HTTP请求,同时(并行)发送一系列类似的HTTP请求。这样我就不必等待(可能延迟的)响应,因为其他系列可以继续。

事实是,每秒的请求数不能超过某个值;让我们说每秒一个请求。所以我需要确保两个并行线程的组合请求频率不超过这个值。

任何帮助将不胜感激。抱歉,如果解决方案很明显,我对python来说还是一个新手。

3 个答案:

答案 0 :(得分:1)

Raymond Hettinger在这里讨论了考虑并发和多线程的正确方法:https://www.youtube.com/watch?v=Bv25Dwe84g0&t=2

他的笔记可以在这里找到:https://dl.dropboxusercontent.com/u/3967849/pyru/_build/html/index.html

我建议,这是来自谈话,是使用原子消息队列在线程之间“对话”。然而,这次谈话和Raymond的工作是在3.5或3.6中完成的。此库https://docs.python.org/3/library/queue.html将为您提供显着帮助。

答案 1 :(得分:1)

强制执行速率限制要求的常用方法是使用Token Bucket方法。

特别是在Python中,您在线程之间共享一个队列,并且第三个线程(可能是原始启动线程)每秒将一个插件对象放入队列。 (也就是说,它是一个简单的循环:等待1秒钟,放置一个物体,重复。)

两个工作线程都尝试从队列中获取一个对象,并且对于每个对象,它们发出一个请求。瞧!工作人员总共可以发出更多的请求,而不是可用的令牌(等于已经过的秒数。即使一个线程停留在长时间运行的请求上,另一个也可能只是一个重复获取一个令牌。它可以推广到N个线程:它们只是竞争从共享队列中获取下一个允许一个请求令牌。

如果许多线程卡在长时间运行的请求中,则会在队列中收集多个令牌,从而允许一连串的追赶请求 - 但仍然只能在较长时间内达到总体目标平均请求数。 (通过调整队列的最大大小,或者是否预先加载了少量的令牌,可以调整限制的确切执行 - 例如,使其在10秒或30秒内收敛到正确的限制,或3600,无论如何。)

共享队列也可以是用于干净地告诉工作线程退出的机制。也就是说,无论信号对象意味着什么,而不是推入队列,"做一个请求",外部控制线程可以将对象推入队列,意味着"完成并退出"。推入N个这样的对象将导致N个工作线程分别获得命令。

答案 2 :(得分:0)

好像你需要一个"信号量"。来自python2.7文档:

  

信号量管理一个内部计数器,该计数器由每个acquire()调用递减,并由每个release()调用递增。计数器永远不会低于零;当acquire()发现它为零时,它会阻塞,等待其他线程调用release()。

因此,你的这个信号量基本上是一个调用计数器,每秒重置为允许的速率,由所有HTTP线程共享。如果它达到0,则没有线程可以再发出请求,直到另一个线程释放连接或第二次传递并且计数器再次被填充。

您可以使用x HTTP请求工作人员和一个HTTP呼叫速率重置工作人员设置脚本:

  • 重置器会破坏并重新生成信号量
  • 每个工作人员获取()每个HTTP都被创建。

如果您使用的是Python2.7和线程,可以在此处找到所有文档: https://docs.python.org/2/library/threading.html

这里有一个很好的教程: https://pymotw.com/2/threading/