5

Ich verschwendete viel Zeit, konnte aber keine Lösung finden.
Wenn ich Threads in meiner App verwende, die mit uwsgi bereitgestellt werden, sind sie nicht synchronisiert.Python3 Threading mit uWSGI

Hier einfacher Code für ein Beispiel (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()] 

Und wenn ich laufe dies den i Anstieg der log-App, aber ich habe immer 1 erhalten, wenn eine Make-Anforderung von Browser (oder erhalten. 0 wenn ich bewege sleep(3) vor i ersten Schritt)
Ich habe versucht, uwsgi.thread Dekorateur, aber das gleiche Ergebnis.

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 für mein Englisch

Antwort

5

Dies geschieht, weil nach der Anwendung der Master-Prozess gabelt sich in einen Arbeiter importieren:

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

So Ihre Threads, i druckt im Master-Prozess ausgeführt wird, und Ihre Anfragen werden vom Arbeiter verarbeitet. Der Worker während der Gabelung sieht i gleich 1. Wenn Sie sleep vor dem Inkrementieren i verschieben, schafft es der Prozess, vor dem ersten Inkrement zu verzweigen.

Sie sollten so etwas wie uwsgidecorators.thread verwenden:

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()] 

Threads außer dem Haupt man nicht während einer Gabel kopiert.

oder -nutzung:

[uwsgi] 
master = false 
+0

Sie haben meine geistige Gesundheit gerettet. 'master = false' genug für meine aktuelle Aufgabe. Aber eine kurze Frage: Wenn ich Ihren Code mit '@ Postfork' verwende, habe ich' print' Ergebnis im Log zweimal für jede Iteration. Warum? – n4nn31355

+0

@ n4nn31355 Ich konnte das nicht reproduzieren. Ich denke, es hat mit Ihrer Protokollierungskonfiguration zu tun. Oder vielleicht haben Sie zwei Prozesse, die in dieselbe Protokolldatei schreiben. – warvariuc

1

Python threading standardmäßig in uwsgi deaktiviert ist, können Sie es --enable-threads durch Hinzufügen Option aktivieren:

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

Es funktioniert in meiner Testumgebung.

+1

Themen sind bereits in der Konfigurationsdatei aktiviert. –