socketio.emit() 在线程中使用 Windows 上的 Popen 进行交互时不起作用
socketio.emit() doesn't work when interacting using Popen on Windows in a Thread
我认为快速的代码片段更能解释我的问题,所以请看一下:
from flask import Flask
from flask.ext.socketio import SocketIO
from threading import Thread
import subprocess
import threading
from eventlet.green.subprocess import Popen
app = Flask(__name__)
socketio = SocketIO(app)
def get_tasks_and_emit():
instance = Popen(["tasklist"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=1)
lines_iterator = iter(instance.stdout.readline, b"")
data = ""
for line in lines_iterator:
data += line.decode("utf8")
socketio.emit("loaded", data)
print("::: DEBUG - returned tasks with thread")
@app.route("/")
def index():
html = "<!DOCTYPE html>"
html += "<script src=https://code.jquery.com/jquery-2.2.0.min.js></script>"
html += "<script src=https://cdn.socket.io/socket.io-1.4.5.js></script>"
html += "<script>"
html += "var socket = io.connect(window.location.origin);"
html += "socket.on('loaded', function(data) {alert(data);});"
html += "function load_tasks_threaded() {$.get('/tasks_threaded');}"
html += "function load_tasks_nonthreaded() {$.get('/tasks');}"
html += "</script>"
html += "<button onclick='load_tasks_nonthreaded()'>Load Tasks</button>"
html += "<button onclick='load_tasks_threaded()'>Load Tasks (Threaded)</button>"
return html
@app.route("/tasks")
def tasks():
get_tasks_and_emit()
print("::: DEBUG - returned tasks without thread")
return ""
@app.route("/tasks_threaded")
def tasks_threaded():
threading.Thread(target=get_tasks_and_emit).start()
return ""
if __name__ == "__main__":
socketio.run(app, port=7000, debug=True)
我 运行 Windows 使用 eventlet 的这段代码,如果我不使用 eventlet 一切都很好(但由于 werkzeug 线程模式,当然要慢得多)。 (我刚刚检查了一下,它也没有在 Linux 上工作)
我希望有人能指出我正确的方向。 (顺便说一句,我的Python版本是3.5.1)
我发现了问题。显然你必须猴子修补线程模块,所以我添加了
import eventlet
eventlet.monkey_patch(thread=True)
然后我也遇到了长 运行 程序的问题。我和这个 Whosebug post 中的人有同样的问题:
所以我添加了
eventlet.sleep()
到处理管道的 for 循环。
编辑:
正如 temoto 指出的那样,或者也可以像这样使用 eventlet.green
中的线程模块:
from eventlet.green import threading
我认为快速的代码片段更能解释我的问题,所以请看一下:
from flask import Flask
from flask.ext.socketio import SocketIO
from threading import Thread
import subprocess
import threading
from eventlet.green.subprocess import Popen
app = Flask(__name__)
socketio = SocketIO(app)
def get_tasks_and_emit():
instance = Popen(["tasklist"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=1)
lines_iterator = iter(instance.stdout.readline, b"")
data = ""
for line in lines_iterator:
data += line.decode("utf8")
socketio.emit("loaded", data)
print("::: DEBUG - returned tasks with thread")
@app.route("/")
def index():
html = "<!DOCTYPE html>"
html += "<script src=https://code.jquery.com/jquery-2.2.0.min.js></script>"
html += "<script src=https://cdn.socket.io/socket.io-1.4.5.js></script>"
html += "<script>"
html += "var socket = io.connect(window.location.origin);"
html += "socket.on('loaded', function(data) {alert(data);});"
html += "function load_tasks_threaded() {$.get('/tasks_threaded');}"
html += "function load_tasks_nonthreaded() {$.get('/tasks');}"
html += "</script>"
html += "<button onclick='load_tasks_nonthreaded()'>Load Tasks</button>"
html += "<button onclick='load_tasks_threaded()'>Load Tasks (Threaded)</button>"
return html
@app.route("/tasks")
def tasks():
get_tasks_and_emit()
print("::: DEBUG - returned tasks without thread")
return ""
@app.route("/tasks_threaded")
def tasks_threaded():
threading.Thread(target=get_tasks_and_emit).start()
return ""
if __name__ == "__main__":
socketio.run(app, port=7000, debug=True)
我 运行 Windows 使用 eventlet 的这段代码,如果我不使用 eventlet 一切都很好(但由于 werkzeug 线程模式,当然要慢得多)。 (我刚刚检查了一下,它也没有在 Linux 上工作)
我希望有人能指出我正确的方向。 (顺便说一句,我的Python版本是3.5.1)
我发现了问题。显然你必须猴子修补线程模块,所以我添加了
import eventlet
eventlet.monkey_patch(thread=True)
然后我也遇到了长 运行 程序的问题。我和这个 Whosebug post 中的人有同样的问题:
所以我添加了
eventlet.sleep()
到处理管道的 for 循环。
编辑:
正如 temoto 指出的那样,或者也可以像这样使用 eventlet.green
中的线程模块:
from eventlet.green import threading