Python 作用域和线程问题

标签 python multithreading scoping

我有一个线程插入到 queueStream(此处未显示)和 FlowController,如果队列不为空,它是从队列中弹出的另一个线程。

我使用 addToQueue() 中的调试代码验证数据已正确插入队列

问题是,FlowController 中的“if queueStream”语句总是将 queueStream 视为空,而是转到 else 语句。

我是 Python 的新手,我觉得我缺少某种简单的范围规则。我正在使用“全局队列流”,但它似乎没有做任何事情。

感谢您的帮助。

from stream import *
from textwrap import TextWrapper
import threading
import time


queueStream = []

class FlowController(threading.Thread):
    def run(self):
        global queueStream
        while True:
            if queueStream:
                print 'Handling tweet'
                self.handleNextTweet()
            else:
                print 'No tweets, sleep for 1 second'
                time.sleep(1)

    def handleNextTweet(self):
        global queueStream
        status = queueStream.pop(0)
        print self.status_wrapper.fill(status.text)
        print '\n %s  %s  via %s\n' % (status.author.screen_name, status.created_at, status.source)


def addToQueue(status):
    print 'adding tweets to the queue'
    queueStream.append(status)

    #debug
    if queueStream:
        print 'queueStream is non-empty'

if __name__ == '__main__':
    try:
        runner = RunStream()
        runner.start()
        flow = FlowController()
        flow.start()
    except KeyboardInterrupt:
        print '\nGoodbye!'

编辑::::::::::::::

感谢您到目前为止的帮助。 Queue 文档很好,自 get() 函数 block 以来帮助我编写了更清晰的代码(酷!)。不管怎样,还是没有解决我的问题,但是我在传递给FlowController之前和之后打印出了queueStream实例,它们有两个不同的内存位置。这就是为什么我相信没有从 FlowController 的队列中弹出任何东西的原因。这是否意味着 Python 按值而不是按引用传递 queueStream?如果是这样,我该如何解决?

from stream import *
from textwrap import TextWrapper
from threading import Thread
from Queue import Queue
import time


class FlowController(Thread):
    def __init__(self, queueStream):
        Thread.__init__(self)
        self.queueStream=queueStream

    def run(self):
        while True:
            status = self.queueStream.get()
            print self.status_wrapper.fill(status.text)
            print '\n %s  %s  via %s\n' % (status.author.screen_name, status.created_at, status.source)


def addToQueue(status):
    print 'adding tweets to the queue'
    queueStream.put(status)

queueStream = Queue()
if __name__ == '__main__':
    try:
        runner = RunStream()
        runner.start()
        flow = FlowController(queueStream)
        flow.start()
    except KeyboardInterrupt:
        print '\nGoodbye!'

最佳答案

如果没有看到 RunStream,很难调试这个问题。 所以我试着想出一个可能会出现问题的简单 RunStream。

我无法重现问题,但这段代码似乎有效。 如果它确实有效并且与您的 RunStream 足够相似,也许您可​​以将此代码与您自己的代码进行比较以找出问题所在。

import threading
import time
import Queue
import sys
import random

class FlowController(threading.Thread):
    def __init__(self,queueStream):
        threading.Thread.__init__(self)        
        self.queueStream=queueStream
    def run(self):
        while True:
            if not self.queueStream.empty():
                print 'Handling tweet'
                self.handleNextTweet()
            else:
                print 'No tweets, sleep for 1 second'
                time.sleep(1)
    def handleNextTweet(self):
        status = self.queueStream.get()
        print(status)

class RunStream(threading.Thread):
    def __init__(self,queueStream):
        threading.Thread.__init__(self)
        self.queueStream=queueStream
    def run(self):
        i=0
        while True:
            addToQueue(self.queueStream,i)
            i+=1
            time.sleep(random.randint(0,2))

def addToQueue(queueStream,status):
    print 'adding tweets to the queue'
    queueStream.put(status)
    if not queueStream.empty():
        print 'queueStream is non-empty'

if __name__ == '__main__':
    queueStream = Queue.Queue()
    try:
        runner = RunStream(queueStream)
        runner.daemon=True
        runner.start()
        flow = FlowController(queueStream)
        flow.daemon=True
        flow.start()
        time.sleep(100)
    except KeyboardInterrupt:
        pass
    finally:
        print('Bye!')

关于Python 作用域和线程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3728577/

相关文章:

python - 让 python 程序等到 Twisted deferred 返回一个值

java - 在java中杀死一个正在运行的线程?

c# - WPF VisualTreeHelper.HitTest 使用多线程

R Shiny 的对象范围

Python 在发出 10 个请求时休眠

python - 对 python3 中\b(退格)后面发生的事情感到困惑

python - 如何使用 pyodbc 将 df 提交到 SQL 数据库?

java - 下面的程序有什么问题?Java wait/notify 不起作用

r - 函数内部的attach()

当参数名和变量名相等时,c++类 setter 设置不同的变量