我浪费了很多时间,但无法找到解决方案 如果我在使用uwsgi部署的应用程序中使用线程,则它们不会同步。
这里是一个示例的简单代码(wsgi.py):
from time import sleep
import threading
i = 0
def daemon():
global i
while True:
i += 1
print(i)
sleep(3)
th = threading.Thread(target=daemon, args=())
th.start()
def application(environ, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [str(i).encode()]
当我运行此应用时,i
会增加日志,但是当来自浏览器的make请求时,我总是得到1
。(如果我移动0
,请获取sleep(3)
在i
第一次递增之前}
我试过了uwsgi.thread装饰,但得到了相同的结果。
uwsgi config:
[uwsgi]
socket = 127.0.0.1:3034
plugins-dir = /srv/uwsgi
plugin = python34
uid = py3utils
gid = py3utils
chdir = /srv/python/3/py3utils/tht/app/
wsgi-file = wsgi.py
enable-threads = true
daemonize = %(chdir)/../uwsgi.log
master = true
die-on-term = true
touch-reload = ../uwsgi_restart.txt
*对不起我的英文
答案 0 :(得分:9)
这是因为在导入应用程序后,主进程将分叉到一个worker:
spawned uWSGI master process (pid: 7167)
spawned uWSGI worker 1 (pid: 7169, cores: 1)
spawned uWSGI http 1 (pid: 7170)
因此,打印i
的线程正在主进程中运行,并且您的请求由工作程序处理。 fork期间的worker看到i
等于1.如果在递增sleep
之前移动i
,则进程在第一次递增之前设置为fork。
您应该使用类似uwsgidecorators.thread
的内容:
from time import sleep
import threading
import uwsgidecorators
i = 0
@uwsgidecorators.postfork
@uwsgidecorators.thread
def daemon():
global i
while True:
i += 1
print(i)
sleep(3)
def application(environ, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [str(i).encode()]
在fork之前不会复制除主要线程之外的线程。
或使用:
[uwsgi]
master = false
答案 1 :(得分:1)
默认情况下,uwsgi中禁用了Python线程,您可以通过添加选项--enable-threads
来启用它:
uwsgi --http :8090 --wsgi-file uwsgi_test.py --enable-threads
它适用于我的测试环境。