简体   繁体   English

使用 uWSGI 的 Python3 线程

[英]Python3 threading with uWSGI

I wasted many time but couldn't find a solution.我浪费了很多时间,但找不到解决方案。
If i use threads in my app deployed with uwsgi, they aren't sync.如果我在使用 uwsgi 部署的应用程序中使用线程,它们不会同步。

Here simple code for an example(wsgi.py):这是示例的简单代码(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()]

And when I run this app the i increases in log, but I always get 1 when a make request from browser.(Or get 0 if I move sleep(3) before i first increment)当我运行这个程序中i增加日志,但我总能得到1时,从浏览器中的化妆请求。(或者得到0 ,如果我动sleep(3)之前, i先增量)
I tried uwsgi.thread decorator, but got the same result.我尝试了 uwsgi.thread 装饰器,但得到了相同的结果。

uwsgi config: 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

*sorry for my English *对不起我的英语不好

This happens because after importing your application the master process forks into a worker:发生这种情况是因为在导入您的应用程序后,主进程分叉到一个工作进程中:

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

So your thread which prints i is running in master process, and your requests are processed by the worker.所以你打印i的线程正在主进程中运行,你的请求由工作人员处理。 The worker during the fork sees i equal to 1. If you move sleep before incrementing i the process manages to fork before the first increment.分叉期间的工作人员看到i等于 1。如果您在增加i之前移动sleep进程设法在第一个增量之前分叉。

Threads except the main one are not copied during a fork, so i does not increment in the worker.在分叉期间不会复制除主线程之外的线程,因此i不会在工作线程中增加。

You should use something like uwsgidecorators.thread :你应该使用类似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()]

Or use:或使用:

[uwsgi]
master = false

Python threading is disabled by default in uwsgi, you can enable it by adding option --enable-threads : Python 线程在 uwsgi 中默认是禁用的,您可以通过添加选项--enable-threads来启用它:

uwsgi --http :8090 --wsgi-file uwsgi_test.py --enable-threads

It works in my test environment.它适用于我的测试环境。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM