Python - while循环里面扭曲的主循环?

时间:2014-12-27 04:16:59

标签: python twisted

我需要知道是否可以在扭曲的websocket主循环中运行while循环

我引用的while循环是你在这个问题中看到的lib:shout-python segmentation fault how can I fix this?

我需要它做的就是在更新后发送新标题,尽管我可以处理那部分。它是while self.running:函数中的play()。如果你能提供帮助,我一定会很感激。

1 个答案:

答案 0 :(得分:2)

对于Twisted的单线程,协同式多任务系统,以最佳方式运行,重要的是在反应堆线程中运行的任何特定代码都不能运行太长时间而不将控制权交还给反应堆。只要在该线程中运行任何一段代码,该线程中就不会运行其他代码。在单线程,协作式多任务系统中,这意味着其他事件不会得到服务。

根据您的应用程序,单个代码运行可能没有放弃控制很多毫秒,很多秒,甚至几分钟。它完全取决于您的应用程序负责处理的事件以及您希望从中获得的响应级别。在为这样的系统编写通用库代码时,大多数人都认为在放弃控制之前,只需几毫秒左右就可以运行单个任务的代码是合适的 - 在合适的情况下犯错误用于更多的应用程序而不是更少的应用程序(尽管人们很少考虑确切的时间限制,大多数操作分为"非常快速"以及其他所有内容)。

几乎总是不可接受的是无限期地运行单个代码而不将控制权交还给反应堆。您链接到的答案中的循环实际上是无限的,因此它将保持控制一段任意长的时间(可能对于程序的大多数运行时)。很少有应用程序可以容忍这种情况,因为结果是永远不会处理其他事件。如果您的应用程序无法响应任何事件,而它将整个运行时间用于单个任务,那么您可能根本不需要多任务处理系统(即,您可能不需要Twisted,您可能只能使用while循环。)

该答案中的循环基本上是一个"尽可能快地处理一些数据"环。对于这种工作的实现有一些选择,其方式更加多任务处理。

一种方法是将环的字面翻译成对反应器友好的模式。您可以使用生成器执行此操作:

from twisted.internet.task import cooperate

class Audio(object):
    def play(self):
        # ... setup stuff ...
        while self.running:
            # ... one chunk of work ...
            yield

def main():
    ...
    cooperate(Audio().play())

cooperate接受一个迭代器并迭代它 - 但不是一次全部。它重复几次,然后放弃对反应器的控制。然后再迭代几次,然后再次放弃控制。这一直持续到迭代器耗尽(或反应器停止)。

另一个稍微不那么直接的翻译是基于LoopingCall,它接管了循环结构的责任,只留下你提供循环的主体:

from twisted.internet.task import LoopingCall

class Audio(object):
    def play(self):
        # ... setup stuff ...

        LoopingCall(self._play_iteration).start(0)

    def _play_iteration(self):
        # ... one chunk of work

这使您可以控制循环迭代的速率。在此示例中传递给0的{​​{1}}表示"尽可能快" (在迭代之间等待0秒) - 同时保持与系统的其余部分协作。如果您希望每秒进行一次迭代,则可以传递start等等。

另一个不太文字的选择是使用数据流抽象 - 例如,Twisted的本地生产者/消费者系统或更新的tubes库 - 来设置更多任务友好的数据处理流程特定"读取,处理"的抽象在链接的答案中循环。