使用uWSGI进行Python3线程处理

n4n*_*355 10 python multithreading python-multithreading uwsgi python-3.x

我浪费了很多时间,但找不到解决方案.
如果我在使用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()]
Run Code Online (Sandbox Code Playgroud)

当我运行这个应用程序i增加日志,但我总是得到1来自浏览器的make请求.(或者0如果我sleep(3)i第一次增量之前移动)
我尝试了uwsgi.thread装饰,但得到了相同的结果.

uwsgi配置:

[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
Run Code Online (Sandbox Code Playgroud)

*对不起我的英语不好

war*_*iuc 11

发生这种情况是因为在导入应用程序后,主进程将分叉到一个worker:

spawned uWSGI master process (pid: 7167)
spawned uWSGI worker 1 (pid: 7169, cores: 1)
spawned uWSGI http 1 (pid: 7170)
Run Code Online (Sandbox Code Playgroud)

因此,您打印的线程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()]
Run Code Online (Sandbox Code Playgroud)

除了主要线程之外的线程在fork期间不会被复制.

或使用:

[uwsgi]
master = false
Run Code Online (Sandbox Code Playgroud)