Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python作用域和线程问题_Python_Multithreading_Scoping - Fatal编程技术网

Python作用域和线程问题

Python作用域和线程问题,python,multithreading,scoping,Python,Multithreading,Scoping,我有一个线程插入queueStream(此处未显示)和FlowController,如果队列不是空的,它是从队列弹出的另一个线程 我使用addToQueue()中的调试代码验证了数据是否正确插入队列 问题是,FlowController中的“if queueStream”语句总是将queueStream视为空,而转到else语句 我是Python新手,我觉得我缺少一些简单的范围规则。我正在使用“全局队列流”,但它似乎没有任何作用 谢谢你的帮助 from stream import * from

我有一个线程插入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!'
编辑:

谢谢你迄今为止的帮助。队列文档很好,帮助我编写了更干净的代码,因为get()函数阻塞了(很酷!)。无论如何,它仍然没有解决我的问题,但我在将queueStream实例传递给FlowController之前和之后打印了它,它们有两个不同的内存位置。这就是为什么我相信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非常相似,那么您可以将此代码与您自己的代码进行比较,找出错误所在

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专家,但我相信即使在模块级函数中也必须声明全局变量


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

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

RunStream()是另一个线程,它调用addToQueue(status)函数并将状态添加到队列中。你可能还想看看,也许会让生活更轻松一些:)我支持@bronzebeard的评论。如果你想快速,不要使用线程。至少在CPython中是这样。如果要将新值分配给
queueStream
并使该值可以通过名称
queueStream
在其他名称空间中访问,则只需使用
global queueStream
。这里,正在对
queueStream
调用一个方法。无论是否声明
queueStream
global
,此效果都是可见的,因为没有重新分配标识符。啊,很有趣。我会留下这个答案,即使它不正确,因为其他人可能会发现你的评论有用谢谢,虽然我没有使用这个解决方案,但它给了我解决这个问题的基本思路。我没有包括RunStream,因为它使用了一个库,并且有点混乱。基本上为了解决这个问题,我将addToQueue()和queueStream移动到FlowController中,然后将FlowController的一个实例传递给RunStream,这样它就可以将addToQueue直接传递给FlowController的实例。FlowController访问queueStream没有问题,因为它现在在该类中。谢谢大家的帮助