5

Ho perso tempo ma non sono riuscito a trovare una soluzione.
Se utilizzo i thread nella mia app distribuiti con uwsgi, non sono sincronizzati.Filettatura Python3 con uWSGI

Qui semplice codice per un esempio (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()] 

E quando ho eseguire questa applicazione i i aumenti di registro, ma ottengo sempre 1 quando una richiesta di make dal browser (o GET. 0 se cambio sleep(3) prima del i primo incremento)
Ho provato il decoratore uwsgi.thread, ma ho ottenuto lo stesso risultato.

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 

* dispiace per il mio inglese

risposta

5

Questo accade perché dopo aver importato l'applicazione delle forche processo maestro in un lavoratore:

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

Così il vostro thread che stampa i è in esecuzione in corso padrone, e le richieste vengono elaborate dal lavoratore. L'operatore durante il fork vede i uguale a 1. Se si sposta sleep prima di incrementare i, il processo riesce a fork prima del primo incremento.

Si dovrebbe usare qualcosa di simile 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()] 

discussioni tranne quello principale non vengono copiati nel corso di una forchetta.

o usare:

[uwsgi] 
master = false 
+0

Hai salvato il mio equilibrio mentale. 'master = false' abbastanza per il mio compito corrente. Ma una domanda veloce: se uso il tuo codice con '@ postfork' ho ottenuto il risultato' print' nel registro due volte per ogni iterazione. Perché? – n4nn31355

+0

@ n4nn31355 Non riesco a riprodurre questo. Quindi penso che abbia a che fare con la tua configurazione di registrazione. O forse hai due processi che scrivono nello stesso file di log. – warvariuc

1

Python threading è disabilitato di default in uwsgi, è possibile abilitarlo con l'aggiunta di un'opzione --enable-threads:

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

E funziona nel mio ambiente di test.

+1

Le discussioni sono già abilitati nel file di configurazione. –