Python 线程一瓶应用程序

Python 线程一瓶应用程序,python,multithreading,bottle,Python,Multithreading,Bottle,我有一个简单的瓶子脚本,在网页上转发按钮进程。在同一个脚本中,我希望有一个连续的循环,在其他任务中,可以监听这些按钮的按下。我试图在一个单独的线程中运行瓶子脚本,但它没有像我预期的那样工作 有没有更好的(或者我应该说是正确的)方法 from bottle import get, post, request, run, redirect import threading @get('/button') def button(): return ''' <form a

我有一个简单的瓶子脚本,在网页上转发按钮进程。在同一个脚本中,我希望有一个连续的循环,在其他任务中,可以监听这些按钮的按下。我试图在一个单独的线程中运行瓶子脚本,但它没有像我预期的那样工作

有没有更好的(或者我应该说是正确的)方法

from bottle import get, post, request, run, redirect
import threading

@get('/button')
def button():
    return '''
        <form action="/button" method="post">
            <input type="submit" value="Push" />
        </form>
    '''

@post('/button')
def action():
    print "button pushed"
    pushed = True
    redirect("/button")

#run(host='localhost', port=8080)
threading.Thread(target=run, kwargs=dict(host='localhost', port=8080)).start()


def method():
    pushed = False
    print "started"
    while 1:
        # do other stuff
        if pushed:
            print "push recieved"
            pushed = False

method()
从瓶子导入获取、发布、请求、运行、重定向
导入线程
@获取(“/按钮”)
def按钮():
返回“”'
'''
@post(“/按钮”)
def action():
打印“按下按钮”
推送=真
重定向(“/按钮”)
#运行(host='localhost',port=8080)
threading.Thread(target=run,kwargs=dict(host='localhost',port=8080)).start()
def方法():
推送=错误
打印“已启动”
而1:
#做其他事情
如果推送:
打印“已接收推送”
推送=错误
方法()

它不起作用,因为它只看到在
方法
中定义的局部变量
被推压
,而不是全局可见且可修改的
被推压
变量

您需要的是以下内容(但向下滚动以获得正确的解决方案):

get_nowait();否则它会立即引发
。您还可以将非零超时传递给它,或者在没有超时的情况下调用它,在这种情况下,它将等待队列中有可用的内容

最好使用带有超时的
.get()
,而不是nowait版本,这样线程就不会无用地消耗CPU

此外,诸如线程起始行以及调用
method()
的代码不应直接放入模块顶级范围;相反,请有条件地这样称呼他们:

if __name__ == '__main__':
    threading.Thread(target=run, kwargs=dict(host='localhost', port=8080)).start()
    method()

这样,只有直接执行
.py
文件时,代码才会执行,而不是将其作为模块导入时执行。此外,考虑调用<代码> Run()/Cuth>正常,而在线程内放置<代码>方法<代码>。自从我使用python有一段时间了,我忘记了全局关键字。队列模块上的一个很好的例子——我以前只使用过锁。@user2921789:锁更复杂,不可伸缩。使用队列进行线程间通信几乎总是可取的。如果你对此感兴趣,谷歌搜索“演员模型”;同意,这正是我需要/想要的。特别是使用可选的
get()
,它会自动阻止相反的功能。谢谢。@user2921789:在我们讨论这个问题时,我还是建议您研究一个名为Gevent的库:-它是一个很棒的并发库,使用起来比线程简单得多,效率也高得多;请确保检查1.0-RC3或dev,尽管它不是稳定的0.13,现在已经很旧了。+1用于从主线程调用
run
,并将
method
放在新线程中。
from Queue import Queue, Empty

button_pressed = Queue()

@post('/button')
def action():
    button_pressed.put(1)  # can be any value really
    redirect("/button")

def method():
    while True:
        try:
            button_pressed.get_nowait()
        except Empty:
            # NOTE: if you don't do anything here, this thread
            # will consume a single CPU core
            pass
        else:
            print "push recieved"
if __name__ == '__main__':
    threading.Thread(target=run, kwargs=dict(host='localhost', port=8080)).start()
    method()