使用uWSGI进行Python3线程处理

时间:2015-08-17 21:01:52

标签: python multithreading python-3.x uwsgi python-multithreading

我浪费了很多时间,但无法找到解决方案 如果我在使用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

*对不起我的英文

2 个答案:

答案 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

它适用于我的测试环境。