使用 uWSGI 的 Python3 线程

标签 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 增加了,但是当浏览器发出请求时,我总是得到 1。(或者得到 0 如果我在 i 第一次递增之前移动 sleep(3))
我尝试了 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

*对不起我的英语

最佳答案

发生这种情况是因为在导入您的应用程序后,主进程会 fork 到一个工作进程中:

spawned uWSGI master process (pid: 7167)
spawned uWSGI worker 1 (pid: 7169, cores: 1)
spawned uWSGI http 1 (pid: 7170)

所以你打印 i 的线程在主进程中运行,你的请求由工作进程处理。 fork 期间的工作人员看到 i 等于 1。如果您在递增 i 之前移动 sleep,则进程会在第一次递增之前 fork 。

除主线程外,fork 期间不会复制线程,因此 i 不会在 worker 中递增。

你应该使用类似 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()]

或者使用:

[uwsgi]
master = false

关于使用 uWSGI 的 Python3 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32059634/

相关文章:

python - keras如何使用ReduceLROnPlateau

python - 连接 Python 中 re.findall 找到的字符串

C - GTK3 和线程

Python线程进程不阻止 'Not responding'

python - 使函数不等待其内部的其他函数

Python - 通过套接字与子进程通信

python - 从模型的 Meta 子类中获取模型的 app_label

python - python 中的 matplotlib 条件背景色

java - 线程安全简单

python - 如何将 DateTime 对象与整数进行比较?