2

这有点复杂……

基本上,我有这个功能:

def do_loop(self):
    for line in self.connections[0].iter_lines():
            print line

并且,有一个线程不断地在它旁边运行,它会在任意时间改变connections[0].

如果发生这种情况,如果connections[0]被线程从外部更改,则循环将继续使用 old connections[0],我需要不要发生这种情况,我需要它立即使用 new connections[0]

对于某些背景,正在使用, 因此for line in self.connections[0].iter_lines():从 Twitter Streaming API 读取数据。python-requests.iter_lines()

有任何想法吗?提前致谢。

4

2 回答 2

1

我建议以下,作为一个简单的解决方案。基本上,使用连接的副本,并在每次循环后根据源检查副本。

def do_loop( self ):
    while true:
        conn = copy( connections[0] )
        for line in conn.iter_lines():
            print line
            if conn != connections[0]:
                break

它绝不是优雅的,但是如果没有彻底和重新设计大量代码以使其成为线程安全的,它应该可以工作。如果需要,您可以使用return语句离开 while 循环。

于 2012-04-17T20:32:06.840 回答
1

循环将for创建一个迭代器,一次,它不会继续检查self.connections[0]循环。所以正如@mklauber 所说,使用类似threading.Event.

假设我们有一个threading.Event实例 asself.new_conn并且每当有新连接时它就会被设置:

def do_loop(self):
    for line in self.connections[0].iter_lines():
        if self.new_conn.is_set():
            break # or could raise exception here
        print line

如果您只需要立即终止循环,您可以通过使您的.iter_lines()方法成为生成器并让生成器进行检查来处理它:

def iter_lines(self):
    for line in self.connections[0].private_data_lines:
        if self.new_conn.is_set():
            break
        yield line

这很好地封装了循环。您的原始代码将如图所示工作,并且在有新连接时会停止。

于 2012-04-17T22:07:09.560 回答