[Python] Un vero multithread

Manlio Perillo manlio.perillo a gmail.com
Mer 23 Ott 2013 11:56:05 CEST


On 22/10/2013 21:00, Giovanni Vittorio Spina wrote:

Dovresti impostare il tuo user agent in modo che wrappi le linee troppo 
lunghe.  Ed io dovrei buttare via Thunderbird, visto che non è nemmeno 
in grado di fare un rewrap rispettando il quoting...

> Ho implementato un modulo che mette uno stream ffmpeg su una surface
> di pygame e funziona fluidissimo. Sto poi facendo un programma che legge
> uno stream da un sensore laser. Se aggiungo stream video e stream laser,
> nonostante sia tutto su thread separati (modulo thread) i calcoli son
> troppi e lo stream video perde pacchetti con un peggioramento evidente
> della qualità video oppure, limitando al massimo il framerate, è lo
> stream del laser a cedere colpi evidenti.


Innanzitutto, se vuoi sperare di avere una risposta che abbia un minimo 
di senso ed utilità per te, devi fornire più dettagli: cosa e come stai 
facendo, e quali funzioni stai usando.

> Il motivo credo che sia il
> fatto che a livello di calcolo, il modulo thread non implementa un vero
> multithread, ma riunisce comunque tutti sotto un solo processo che
> gestisce con un sistema semaforico particolarmente intelligente.
>

CPython (l'implementazione ufficiale di Python) usa un GIL (Global 
Interpreter Lock) per proteggere l'interprete in un ambiente multi 
threading.  Però le estensioni scritte in C e che non devono accedere 
all'interprete, di solito rilasciano il GIL; questo succede a tutte le 
funzioni che si interfacciano al sistema operativo, come socket, read, 
write e lo stesso immagino valga per pygame.

> Per ovviare il problema avevo pensato di fare un'applicazione che
> legge i dati dal laser e un'altra con interfaccia grafica e con lo
> stream video.
>

Prima di stravolgere il codice, devi cercare di capire cosa è che non va 
nel codice attuale.

Ecco alcuni consigli, e domande per avere maggiori informazioni:

1) Lo stream ffmpeg lo leggi da file e poi lo passi direttamente a
    pygame, vero?  Questo è il motivo per cui è efficiente, dato che
    usa codice scritto in C.

2) Togli di mezzo la visualizzazione dello stream video, e metti il
    codice relativo alla visualizzazione dei dati acquisiti dal laser
    nel thread principale (ossia, *non* usare thread aggiuntivi).

    Hai ancora problemi evidenti di inefficienza?
    Come acquisisci i dati?
    Quanti dati visualizzi alla volta e con che frame rate desiderato?

3) Tolti di mezzo i thread aggiuntivi, usa un profiler per vedere dove
    effettivamente il tuo codice è inefficiente.

    Dalle informazioni che dai io un sospetto ce l'ho.
    Non è che per caso visualizzi un punto alla volta, chiamando una
    funzione tipo show_point(x, y) ?

    Se devi visualizzare un migliaio di punti alla volta per un
    framerate decente, è evidente che stai sovraccaricando pygame.

    Non conosco pygame, ma mi aspetto che fornisca delle funzioni per
    visualizzare un array di punti.

> Come condivido i dati? Non vorrei usare un sistema client server, mi
> piacerebbe qualcosa di più elegante che mi permetta la condivisione di
> un dizionario con 7-8000 valori ad una frequenza di almeno 10 letture al
> secondo... Avete idee?

Ok, questo risponde ad una delle domande.
I dati che acquisisci dal laser li visualizzi direttamente o devi farci 
qualche pre-processamento?

> Grazie


Ciao  Manlio



Maggiori informazioni sulla lista Python