I wasted many time but couldn't find a solution.
If i use threads in my app deployed with uwsgi, they aren't sync.
Here simple code for an example(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 tried uwsgi.thread decorator, but got the same result.
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
*sorry for my English
Running uWSGI in Async mode Each async core can manage a request, so with this setup you can accept 10 concurrent requests with only one process.
uWSGI includes an HTTP/HTTPS router/proxy/load-balancer that can forward requests to uWSGI workers. The server can be used in two ways: embedded and standalone. In embedded mode, it will automatically spawn workers and setup the communication socket.
uwsgi (all lowercase) is the native binary protocol that uWSGI uses to communicate with other servers. uWSGI is often used in conjunction with web servers such as Cherokee and Nginx, which offer direct support for uWSGI's native uwsgi protocol, to serve Python web applications such as Django.
ini configuration file. The threads option is used to tell uWSGI to start our application in prethreaded mode. That essentially means it is launching the application across multiple threads, making our four processes essentially eight processes.
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. 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.
Threads except the main one are not copied during a fork, so i
does not increment in the worker.
You should use something like 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With