Progettazione di applicazioni multi-threading

 

L'obiettivo di progettare una applicazione multi-threading - oltre a garantire che funzioni correttamente - è di scriverla in modo comprensibile e che aiuta a modificarla e evolverla con tempi e sforzi sostenibili. 

Facendo manutenzione e evolvendo l'applicazione mi troverò ad esempio a cercare risposta a domande come queste, e vorrò riuscire a farlo senza bisogno di sacrifici eroici :

  • Sto aggiungendo una nuova classe all'applicazione, quanti thread avranno accesso contemporaneo all'istanza della classe?

  • Sto modificando il metodo di una classe per aggiungergli chiamate a metodi di altre classi, dovrò aggiungere dei lock ? quali e dove ?

  • Ho necessità di distribuire  in 4 thread il carico lavoro che la applicazione ora sostiene su 2 thread , come devo sincronizzazione i 2 nuovi thread ?

 


E' singolare che le applicazioni multi-utente che accedono a un data-base sono molto più semplici da scrivere/modificare/evolvere delle applicazioni multi-threading anche se hanno molte similitudini e molte cose in comune.

I Db relazionali definiscono un modello di programmazione e gestione della concorrenza che bisogna adottare. Nelle applicazione multi-threading  senza questi vincoli uno stesso problema può essere affrontato in una varietà di modi differenti e cosi la ricerca di una soluzione semplice all'inizio è più impegnativa .  Viceversa una volta acquisito un repertorio di soluzioni efficaci l'unico limite per migliorarle, adattarle e reinventarle è la fantasia.


Update 18-5-2008 sintesi di info e riferimenti utili dai comments

Flynn's Taxonomy
- http://en.wikipedia.org/wiki/Flynn_taxonomy
- http://mugur.roz.md/computer-science/computer-science/images/fig09_02_0.jpg

Monads
- http://blogs.ugidotnet.org/dmantovani/archive/2007/11/26/89935.aspx
- http://channel9.msdn.com/ShowPost.aspx?PostID=358968

 Parallel C#
- http://blogs.ugidotnet.org/dmantovani/archive/2008/05/13/92658.aspx

Microsoft Robotics Studio:
- http://msdn.microsoft.com/en-us/robotics/default.aspx
- http://channel9.msdn.com/ShowPost.aspx?PostID=206574

Questi post sul multi-threading sono limitati a linguaggi Object Oriented su hw con architetture classica Von Neumann (cioè architetture control-flow = istruction-flow di tipo SISD e non Multipme Instruction stream Multiple Data strueam e nemmeno a arcitettura  data-flow; vedi la tassonomia di Flynn). Cioè a .NET C# su PC e Server comuni .

 

Tags :   |

Print | posted @ martedì 6 maggio 2008 3.07

Comments on this entry:

Gravatar # re: Progettazione di applicazione multi-threading
by LudovicoVan at 06/05/2008 14.45

Ciao Luca, post molto interessante.

Personalmente sono per l'approccio "tipo database", dove cioe' la concorrenza e' gestita al livello di provider e non di consumer.

Per esempio, in una classe che esegue calcoli matematici e che ha bisogno di sincronizzare l'accesso ad una risorsa condivisa qual e' l'FPU con i suoi settings, ho trovato del tutto naturale gestire la sincronizzazione *nella* classe matematica stessa, piuttosto che nei veri consumer.

Mi si sono poi presentati scenari in cui anche dal consumer avevo bisogno di accesso e controllo sulla FPU, ma anche quel problema si e' risolto facilmente esponendo alcuni metodi comunque dalla classe provider, e continuando a tenere in quest'ultima l'incapsulamento della sincronizzazione, con una crescita "non piu' che lineare" della complessita' del provider, ed una crescita praticamente nulla della complessita' del/dei consumer.

Come ti suona? In particolare, non ho ben capito se arrivi alla stessa conclusione o meno.

-LV
  
Gravatar # re: Progettazione di applicazione multi-threading
by LudovicoVan at 06/05/2008 15.19

P.S.

Non vedo l'ora di avere occasione di mettere le mani sul Microsoft Robotics Studio, ma da quel poco che ho capito risolve egregiamente proprio le varie problematiche di collaboration e synchronization (in contesti real-time o meno, BTW).

In effetti, se ripenso all'esempio che ho fatto sopra, non sono stato molto preciso: quello che alla fine ho implementato e' una classe (con la semantica di una classe statica) che incapsula la FPU stessa, cioe' la risorsa condivisa.

Ripeto, non ho ancora avuto modo di vedere i dettagli del MRS. Aggiunge qualcosa ai termini dell'equazione?

-LV
  
Gravatar # re: Progettazione di applicazione multi-threading
by LudovicoVan at 06/05/2008 15.57

P.P.S.

Gee, the (in)famous self-synchronizing static singleton, finally...

;) -LV
  
Gravatar # re: Progettazione di applicazione multi-threading
by Luca Minudel at 06/05/2008 22.56

> ho trovato del tutto naturale gestire la sincronizzazione *nella* classe matematica stessa, piuttosto che nei veri consumer.

vedo molti vantaggi in questo approccio

> In particolare, non ho ben capito se arrivi alla stessa conclusione o meno

una altra idea da trovare riguarda come fare quando risorse/variabili condivise sono diverse e cosi c'è anche il rischio di dead-lock

provo a dire qualcosa nel prox post

> Non vedo l'ora di avere occasione di mettere le mani sul Microsoft Robotics Studio

ammetto la mia ignoranza sul tema - cos'è ?
  
Gravatar # re: Progettazione di applicazione multi-threading
by LudovicoVan at 07/05/2008 14.37

http://msdn.microsoft.com/en-us/robotics/default.aspx

Guarda in particolare la sezione a fondo pagina: Concurrency and Distribution. Ti consiglierei anche il link al video introduttivo originale (sempre presente in quella pagina), anche se al momemento sembrerebbe non funzionare: http://channel9.msdn.com/ShowPost.aspx?PostID=206574

Il Robotics Studio e' un set di tecnologie la cui applicabilita' va ben al di la' della sola robotica e dei soli sistemi real-time... e, per molti versi, e' concettualmente molto vicino ad un ambiente event-driven puro (ok, non sono molto sicuro di questa mia ultima affermazione...)

-LV
  
Gravatar # re: Progettazione di applicazione multi-threading
by LudovicoVan at 07/05/2008 14.40

> una altra idea da trovare riguarda come fare quando risorse/variabili condivise sono diverse e cosi c'è anche il rischio di dead-lock

> provo a dire qualcosa nel prox post

Ho letto il post, molto ben fatto, ma ti segnalo che le parti in grigio sono quasi illegibili...

Comunque, nella mia /follia/, al problema che qui sollevi risponderei d'un sol fiato: incapsula a piu' alto livello! (Cioe', incapsula tutto il set di risorse condivise.) Ovviamente, fra il dire e il fare c'e' di mezzo il mare...

-LV
  
Gravatar # re: Progettazione di applicazione multi-threading
by Luca Minudel at 07/05/2008 23.30

> Il Robotics Studio e' un set di tecnologie

divertente e interessante

> incapsula a piu' alto livello!


ok ci stà tutta

e scommetto c'è modo di riuscirci rispettando oltre l'incapsulamento anche la suddivisione di responsabilità tra oggetti

> le parti in grigio sono quasi illegibili...

hai usato qualche trucco x leggerle lo stesso ?


  
Gravatar # re: Progettazione di applicazione multi-threading
by LudovicoVan at 08/05/2008 2.40

Of course: basta mettere il foglio sotto una lampada a incandescenza per 30+ secondi...

-LV
  
Gravatar # re: Progettazione di applicazione multi-threading
by LudovicoVan at 08/05/2008 2.46

> e scommetto c'è modo di riuscirci rispettando oltre l'incapsulamento anche la suddivisione di responsabilità tra oggetti

Se e' una domanda seria: si', si tratta di incapsulare in un contesto che non si limta ad esporre una facciata, bensi' gestisce l'orchestrazione; cioe' il tutto e' maggiore della somma delle parti. Hmm, mi sa che la domanda non era troppo seria...

Scherzi a parte, ho letto anche il tuo articolo no. 3: molto interessante! Probabilmente ho descritto un possibile approccio al "modello a competizione". D'acchitto non saprei se discorso simile si puo' estendere al "modello a sincronizzazione". Ci pensero'...

-LV
  
Gravatar # re: Progettazione di applicazione multi-threading
by Luca Minudel at 08/05/2008 9.27

> Se e' una domanda seria: si'

si, è seria, mi riprometto di raccogliere idee/suggerimenti e farne un post

se hai 2 oggetto ogniuno del quale implementa il lock appal propria risorsa come fai a implementare l'orchestrazione senza rospere l'icapsulamento e spostare questa responsabilità ?
  
Gravatar # re: Progettazione di applicazione multi-threading
by LudovicoVan at 08/05/2008 17.08

Se ti sto capendo bene, non rompi l'incapsulamento, semmai stratifichi (o "wrappi"). Ciascun oggetto incapsula la sua propria sincronizzazione, mentre a piu' altro livello ulteriormente incapsuli l'orchestrazione di tali sincronizzazioni. Un po' come le matrioske. Il tutto ad uso dei vari consumer e *rigorosamente* trasparente ad essi (il che resta il criterio ultimo da rispettare).

Comunque un esempio qui potrebbe valere piu' di mille parole. Appena riesco, provo a mettere in piede una sorta di proof of concept, magari proprio a partire dal codice C++ che ho dovuto scrivere per la suddetta libreria matematica.

Se ce la faccio, ti faccio sapere!

-LV
  
Gravatar # re: Progettazione di applicazione multi-threading
by LudovicoVan at 09/05/2008 0.30

In realta' quel codice non va bene perche' li' l'unica risorsa il cui accesso era da sincronizzare era appunto l'FPU.

Ce l'hai magari tu un esempio base, con almeno un paio di risorse distinte, su cui potrei lavorare? (Penso che mi andrebbe bene anche un esempio alquanto "astratto", purche' ponga - per cosi' dire - problemi di sincronizzazione incrociati...)

-LV
  
Gravatar # re: Progettazione di applicazione multi-threading
by Luca Minudel at 09/05/2008 22.58


Immagina un oggetto ServerListener che gira in un thread , accetta connesioni tcp/ip e per ogni connessione istanzia un Client che gira in un suo thread da cui riceve e invia dati sulla connessione stabilita.

Il ServerListener mantiene riferimento al client avendo una collezione ConnectedClient di tutti i client.

Quindi Client e ConnectedClient sono attraversati da 2 thread.


Quando ServerListener dal suo thread compila la lista e cicla la collezione , la collezione fa il lock della collezione e poi quando accede al client per leggere il nome e id e qui è Client che fa il lock del client.

Quando Client sdal suo "thread" riceve un messaggio di disconnessione dal suo thread fa il lock del client e esegue la disconnessione quindi si togli edalla collezione ConnectedClient che a sua volta fa il lock della collezione.

Tutti i presupposto perchè ci possa essere un deadlock
  
Gravatar # re: Progettazione di applicazione multi-threading
by LudovicoVan at 10/05/2008 13.48

Mhhh, me la riscrivi in Italiano? Altrimenti mi tocca ripartire dall'analisi... logica!

Cioe', e' piuttosto nello statement del problema/soluzione che vedo... problemi, il primo dei quali e' una non ben definita linea di demarcazione fra problema e soluzione, e il secondo dei quali e' che un problema mal posto e' irrisolvibile a priori.

Piu' in generale, considera che non e' una questione di pedanteria bensi' di metodo. Sono infatti un fan del principio: metti a posto lo statement del problema fino all'ultima minuzia, dopodiche' la soluzione sara' banale e auto-evidente.

Comunque, per darti un'idea piu' concreta, di seguito alcune delle cose che d'acchitto mi vengono da notare (ma ripeto, il problema qui e' completamente da riformulare, non si tratta solo di mettere qualche pezza):

1. c'e' una potenziale confusione (terminologica e di responsabilita') fra il ServerListener e il Server tout court;

2. c'e' una potenziale confusione (terminologica) se chiami Client cio' che forse e' piu' propriamente un "worker process" lato server;

3. la gestione della ConnectedClients list dovrebbe essere piuttosto allocata al Server stesso, e non al Listener (cfr. punto 1), ma in ogni caso *mai* essere responsabilita' *anche* del worker process (il tuo "Client"), altrimenti li' si' che rompi l'incapsulamento, o meglio: "incasini" le responsabilita', perche' crei dipendenze cicliche;

In particolare, i seguenti due paragrafi non li capisco proprio:

> Quando ServerListener dal suo thread compila la lista e cicla la collezione , la collezione fa il lock della collezione e poi quando accede al client per leggere il nome e id e qui è Client che fa il lock del client.

"La collezione fa il lock della collezione"? "Il Client fa il lock del client"?? A parte qui la confusione, concettuale e tecnica, fra "processi" e "risorse", direi: ma che cosa ce l'ha a fare il server una lista di connected-clients (worker processes) se poi l'id, nome, ecc., del processo worker lo deve andare a chiedere al worker stesso?

> Quando Client sdal suo "thread" riceve un messaggio di disconnessione dal suo thread fa il lock del client e esegue la disconnessione quindi si togli edalla collezione ConnectedClient che a sua volta fa il lock della collezione.

Idem per "il client che fa il lock del client", nonche' per il fatto che incasini le responsabilita' se e' il client che si toglie dalla collection dei client; il "client" (e lo ripeto, e' piuttosto un "worker") dovrebbe piuttosto *notificare* il "server" (il processo main) e quest'ultimo poi fa quello che deve fare, incluso gestire la sua lista dei worker.

Insomma, il problema c'e', ma e' a monte!

BTW, qui l'unica risorsa condivisa (sempre ricordando che componenti, processi e risorse non sono la stessa cosa) sembrerebbe appunto la worker-processes list, e null'altro.

Infine, considera che l'ultima volta che ho fatto socket programming serio era il 1998, per cui una descrizione un po' piu' concettuale (Analisi, ovvero lo statement del problema) e un po' meno tecnologica (Design, ovvero il disegno della soluzione) mi aiuterebbe alquanto... altrimenti devi essere **molto** piu' preciso, e **molto** piu' dettagliato.

Tutto cio' detto, torniamo a noi: qui e' lo statement del problema a fare acqua, e povero il programmatore che si trova a lavorare con una "specifica" del genere...

Avrei potuto infatti rispondere in una sola riga: non ci ho capito niente!! Ma e' sabato mattina e, come al solito, non ho niente da fare...

;) -LV
  
Gravatar # re: Progettazione di applicazione multi-threading
by Luca Minudel at 10/05/2008 17.30

Ok

Stiamo parlando di applicazione che gira su di un PC in rete, è in ascolo su una porta tcp/ip e avvia una nuova connessione tcp/ip con ogni chiamante che la contatta.
Resta in ascolto su ogni connessione che ha aperto e riceve i dati inviati.

Questa è la porzione di applicazione che ci interessa.

Immagina di avere del codice legacy che implementa tutto ciò e che ognitatnto si blocca perchè va in deadlock.
E' chiaro fino a qua?
  
Gravatar # re: Progettazione di applicazione multi-threading
by LudovicoVan at 10/05/2008 18.21

Diciamo di si', anche se - a rigore - a questo stadio il dead-lock e' solo un'ipotesi.

Ti segnalo inoltre che ci stiamo avventurando in una sessione di debug piuttosto che nella individuazione di una soluzione ad un problema posto da zero, per cui il tutto e' ulteriormente complicato dal fatto che si tratta di partire dal reverse-engineering di qualcosa che non funziona e che potrebbe essere errato fin dall'impostazione.

Tant'e' che, se il budget (tempi/costi) fosse illimitato (situazione ideale), ti direi: butta il programma che hai, riparti dall'analisi, mettila a posto, e riscrivi da zero...

Comunque, ok: diciamo che fin qui ci sono.

(BTW, in quel famoso 1998, e' proprio qualcosa del genere che mi e' toccato scrivere, e di problemi di dead-lock manco uno... nonostante si trattava di un'applicazione assolutamente non banale, con decine di deamon in ascolto e migliaia di thread in concorrenza, aperti e chiusi di continuo. Cioe' la tua applicazione ha piuttosto un "bug" (in senso lato e piu' o meno profondo), ma non ci sono problemi *intrinseci*... che era cio' che piuttosto ti chiedevo. Magari bottom-line, questo gia' dimostra la mia tesi iniziale: sull'efficacia delle matrioske! Ma ok, andiamo avanti...)

-LV
  
Gravatar # re: Progettazione di applicazione multi-threading
by Luca Minudel at 10/05/2008 19.47

Ci siamo.

Le classi del codice legacy che stiamo ipotizzando e che hanno il bug del dead-lock sono 3, eccole descritte


* ServerListener
- ha la responsabilità di ascoltare sulla porta tcp/ip le richieste di connessione
- quando un chiamante contatta la porta tcp/ip...
--- avvia la connessione
--- creare una istanza della classe Client a cui ha passato la connessione
--- aggiunge l'istanza appena creata alla collezione ConnectedClient



* Client
- conosce la connessione tcp/ip aperta su cui è in ascolto
- ha la responsabilità di ricevere inviati sulla connessione
- ha la responsabilità di sollevare un evento di notifica quando la
connessione viene chiusa (dall'altro capo)


* ConnectedClient
- conosce tutte le istanze di Client che gli sono state aggiunte
- ha la responsabilità di aggiungere nuove istanze di Client quando gli sono passate (Add)
- ha la responsabilità di rimuove una istanza di Client quando gli viene richiesto (Remove)


* ServerListener
- quando una istanza di Client notifica un evento di chiusura ha la responsabilità di
rimuovere il client dalla collezione ConnectedClient



Ci siamo fin qui, passo ai thread ?

  
Gravatar # re: Progettazione di applicazione multi-threading
by Luca Minudel at 11/05/2008 12.15

> Magari bottom-line, questo gia' dimostra la mia tesi iniziale: sull'efficacia delle matrioske!

divertente , quel modo di mettere i lock l'ho chiamato allo stesso modo con un collega , mi sa che è la metafora giusta x descriverlo
  
Gravatar # re: Progettazione di applicazioni multi-threading
by LudovicoVan at 12/05/2008 0.52

Fin qui mi pare di esserci... c'e' in realta' qualcosa che mi "puzza", ma potrebbe banalmente essere la mia riluttanza per la terminologia OO delle "responsabilita'" applicata alla ClientConnectedList, che mi sembrerebbe una banale data structure; comunque, procedi pure...

-LV
  
Gravatar # re: Progettazione di applicazioni multi-threading
by Luca Minudel at 12/05/2008 22.44


Nella applicazione ci sono 2 thread in esecuzione.

* Il "Listener Thread" in cui gira
- il metodo di ServerListener che è in ascolto delle richieste di connessione; le soddisfa come descritto sopra e torna in ascolto
- i metodi di iterazione dei client e AddNew di ConnectedClient (richiamati da ServerListener)
- il costruttore del Client e alcuni get delle proprietà di Client (richiamati sempre dal AddNew di ConnectedClient)

* Un "Receive Thread" per ogni Client connesso, in cui ci gira
- il metodo receive in cui ogni Client sta in ascolto e esegue la ricezione come descritto sopra
- quando il messaggio è di chiusura della connessione solleva un evento che viene ricevuto da ConnectedClient e che rimuove il client

C'è una istanza di ServerListener, una di ConnectedClient e enne di Client.



E questi sono i lock
* ConnectedClient è una collezione sincronizzata nel senso classico di .NET cioè quando eseque l'iterazione, l'AddNew, ect acquisisce un lock a un SYncRoot che è un field privato di istanza.
* Client anche lui acquisisce un lock a un SYncRoot field privato di istanza durante l'esecuzione di ogni suo metodo/proprietà pubblica



Dead-Lock

Questo il grafo di acquisizione dei lock in "Listener Thread" durante la sequenza di chiamate di ServerListener quando accetta una nuova connessione:
-> Lock su ConnectedClient.SyncRoot +-> Lock sul Client.SyncRoot di ogni istanza di Client già nella collezione

-> Lock su ConnectedClient.SyncRoot +-> Lock sul Client.SyncRoot del client appena istanziato


Questo il grafo di acquisizione dei lock in "Receive Thread" durante la sequenza di chiamate di una istanza di Client quando riceve il messaggio di chiusura della connessione:
Lock su ConnectedClient.SyncRoot <-- Lock sul Client.SyncRoot di ogni istanza di Client già nella collezione <-

Se un client riceve nel "Receive Thread" un messaggio di chisusra connessione proprio mentre il "Listener Thread" sta ciclando su quel client, c'è un dead-lock



Questo è il quadro del codice legacy ipotetico che stiamo guardando.
Se è chiaro anche questo torno passo alla domanda , all'idea da scoprire



  
Gravatar # re: Progettazione di applicazioni multi-threading
by LudovicoVan at 13/05/2008 22.19

Lo smell si conferma. Per il resto, ok, procedi pure.

BTW, poi ti faccio vedere un esempio che e' venuto fuori ad una recente intervista (sono di nuovo a caccia di lavoro), in cui c'e' un dead-lock potenziale, il quale probabilmente si trasforma in dead-lock attuale in uno scenario in cui i carichi sono significativi.

Ti anticipo solo, e lo ritengo un punto di ragionamento essenziale, che tale potenzialita' intrinseca sorge a causa di un errata (nel senso appunto delle possibili conseguenze nefaste) definizione del *dominio dei dati*!!

-LV
  
Gravatar # re: Progettazione di applicazioni multi-threading
by LudovicoVan at 14/05/2008 6.28

Intanto, molto interessante e molto attinente -- alle matrioske! A me meglio note sotto il nome di "modularita'".

Daniele Mantovani: Functional programming...monoid...monad
http://blogs.ugidotnet.org/dmantovani/archive/2007/11/26/89935.aspx

Brian Beckman: Don't fear the Monads
http://channel9.msdn.com/ShowPost.aspx?PostID=358968

CATHEGORY THEORY
The astonishing consequences

COMPOSITIONALITY
The way to control complexity

"In functional programming, code is data too. We are not scared of that! You can't make a mistake, if you buy into the discipline. Correct by construction!"

F# and BEYOND: ~01:03:00
  
Gravatar # re: Progettazione di applicazioni multi-threading
by LudovicoVan at 14/05/2008 20.37

BTW, tornando al modello a sincronizzazione vs il modello a composizione, cfr. anche questo rapido (ma non indolore! :) scambio a partire da un post sempre di Daniele Manotovani:

Parallel C#
http://blogs.ugidotnet.org/dmantovani/archive/2008/05/13/92658.aspx

L'enfasi sui DATI (la primitiva assoluta che incapsula la complessita' reale del dominio) mi sembra sempre piu' significativa...

-LV
  
Gravatar # re: Progettazione di applicazioni multi-threading
by LudovicoVan at 14/05/2008 22.04

P.S.

Last but not least:

Il Microsoft Robotics Studio e' JavaScript based...!!!

(Non so quanto e' rigorosa, ma so che esprime l'essenziale.)

-LV
  
Gravatar # re: Progettazione di applicazioni multi-threading
by Luca Minudel at 14/05/2008 22.52

grazie dei link - ora ho un po di cose a mente e ho voglia di riordinarle e postarle prima di dimenticarle ... poi me li leggo tutti !!!

questo codice legacy ha di buono che ogni classe implementa e incapsula il suo locking

e ha lo svantaggio che chi le usa può incorrere nel dead-lock e le info per prevenirlo o gestirlo sono un po nascoste

tenendo queste 3 classi la sfida è immaginare un modo di cambiare e disegnare il locking x le operazioni/responsabilità descritte in modo che chi legge il codice capisce la strategia adottata e può mantenerla quando modifica/evolve il codice

ti viene qualche idea al riguardo su questo esempio qui?
  
Gravatar # re: Progettazione di applicazioni multi-threading
by Luca Minudel at 14/05/2008 22.56

p.s x quanto riguarda il parallel C# questo affronta una diversa tipologia di elaborazione parallela cioà una elaborazione data-driven

quella di questa serie di post è coltrol-flow driven.

l'uso del modello data-driven o coltrol-flow driven dall'HW utilizzato.
  
Gravatar # re: Progettazione di applicazioni multi-threading
by LudovicoVan at 15/05/2008 0.46

luKa:

> questo codice legacy ha di buono che ogni classe implementa e incapsula il suo locking

Se proprio non vuoi/puoi toccare il codice preesistente, l'unica strada per me e' appunto quella di incapsulare l'extra-complessita' del locking in un wrapper, che diventa il modulo (o oggetto) con cui dall'esterno ci si interfaccia.

Si tratta quindi di una classe che incapsula l'orchestrazione. In questo modo gli sviluppatori che devono utilizzarla non avranno piu' quel problema. Il costo di astrarre quella funzionalita' in una classe a piu' alto livello secondo me e' trascurabile perche' comunque il 90% dello sforzo e' in ogni caso capire come funziona il sistema originale.

Un buon ausilio per pensare e disegnare tale orchestrazione per me e' ragionare in termini di macchina a stati, con l'ausilio di state e sequence diagrams. Il problema, in un certo senso, diventa algoritmico (event-driven) piuttosto che funzionale (data-driven).

Infine, lo stesso wrapper, per quanto nato per l'orchestrazione, puo' e dovrebbe essere il punto di riferimento per ulteriori estensioni. Di sicuro resta il punto di riferimento non ulteriormente scorporabile di qualunque refactoring.

Resta detto che, se l'unico pregio del codice originale e' che "incapsula il suo locking", a maggior ragione ti direi che lo puoi/dovresti cestinare e riscrivere, perche' e' il modello a monte che e' broken e l'extra-complessita', compresi i problemi di dead-lock, deriva proprio/solo da quello.

Bottom line: Se construisci un wrapper oggi, domani dovrai costruirne un altro... e se ripensi al refactoring e alla non-scorporabilita' ti fai anche un'idea delle proporzioni del problema.

-LV
  
Gravatar # re: Progettazione di applicazioni multi-threading
by LudovicoVan at 15/05/2008 0.47

luKa:

> l'uso del modello data-driven o coltrol-flow driven dall'HW utilizzato.

Scusa, io conosco data-driven e event-driven, e non sono incompatibili, sono piuttosto ortogonali.

A mio avviso e' il modello originale che e' broken, dallo smell direi che c'e' proprio una confusione alla base fra dominio dei dati e dominio del controllo/eventi, cioe' un problema intrinseco alla progettazione, magari facilmente rilevabile ad una semplice ispezione.

Il tuo scenario a dispositivi e' egregiamente coperto proprio dal MRS, ed e' event-driven JavaScript based, cioe' i due viaggiano a bracetto egregiamente. Forse forse implementa addirittura la concorrenza vera, anche se non mi ricordo piu' i dettagli... ma mi ricordo che i dead-lock sono l'ultimo dei problemi, perche' l'"orchestrazione" era proprio uno dei punti di forza assoluti di tutto il progetto MRS, in termini sia di efficacia che di usabilita' dallo sviluppatore.

Ti chiederei: sei almeno d'accordo che la tua libreria e' bacata e che quella del wrapper e' solo una pezza, per lo piu' sconsigliabile salvo cause di forza maggiore?

-LV
  
Gravatar # re: Progettazione di applicazioni multi-threading
by Luca Minudel at 15/05/2008 8.59

> Ti chiederei: sei almeno d'accordo che la tua libreria e' bacata

si, la possibilità che possa avvenire un dead-lock è un bug , intendi questo giusto ?


> quella del wrapper e' solo una pezza, per lo piu' sconsigliabile salvo cause di forza maggiore?

ok. prendiamoci la libertà di cambiare le classi / il disegno

> conosco data-driven e event-driven, e non sono incompatibili, sono piuttosto ortogonali.

si applicano con HW e linguaggi differenti. intendi che si possono utilizzare insieme contemporaneamente ?
  
Gravatar # re: Progettazione di applicazioni multi-threading
by LudovicoVan at 15/05/2008 17.28

> > Ti chiederei: sei almeno d'accordo che la tua libreria e' bacata

> si, la possibilità che possa avvenire un dead-lock è un bug , intendi questo giusto ?

Direi di si'. Nel dubbio, provo a spiegare piu' estesamente: il *disegno* e' bacato (errata individuazione e allocazione dei flussi e delle responsabilita'), e il problema del dead-lock e' solo uno dei tanti problemi che possono insorgere a seguito di un disegno bacato.

Il risultato e' che: o aggiusti il disegno, e a cascata il codice, oppure vai avanti ad oltranza a mettere pezze al codice, perche' quello del dead-lock, di nuovo, e' solo uno dei tanti potenziali problemi.

> > quella del wrapper e' solo una pezza, per lo piu' sconsigliabile salvo cause di forza maggiore?

> ok. prendiamoci la libertà di cambiare le classi / il disegno

No, quella liberta' non ce la possiamo prendere. Cosa dice l'analisi dei requisiti e dei constraint? Cosa, in effetti, ci viene chiesto di fare? Dubito che sia alcunche' della forma "wrapper vs ridisegno". Probabilmente e' piu' della forma "quella funzionalita' li' mi serve/non funziona". Li' trovi tutti gli ok e tutti i no e i perche'.

> > conosco data-driven e event-driven, e non sono incompatibili, sono piuttosto ortogonali.

> si applicano con HW e linguaggi differenti. intendi che si possono utilizzare insieme contemporaneamente ?

Non solo si possono, bensi' si *devono*, nella misura in cui sono le due faccie della stessa medaglia: computazione. A maggior ragione, non si applicano a contesti differenti, per quanto la ripartizione del dominio dei dati e/da qella del dominio del controllo fa si' che una parte dei problemi viene affrontata in un modo, un'altra parte viene affrontata nell'altro modo, e nel complesso entrambe le modalita' *concorrono* a fornire la soluzione nel suo complesso.

Un altro modo di dirlo e' che l'approccio procedurale (imperativo) e l'approccio funzionale (dichiarativo) sono complementari. Se guardi il video sulle Monadi, vedrai che tale scomposizione e' in quel concetto resa molto netta, dove hai da una parte le "funzioni" e dall'altra i "construttori". Ti consiglio il video caldamente...

-LV
  
Gravatar # re: Progettazione di applicazioni multi-threading
by Luca Minudel at 15/05/2008 21.51

> No, quella liberta' non ce la possiamo prendere. Cosa dice l'analisi dei requisiti e dei constraint?

parti dalla descrizione del servizio erogato dal sw che è chiara.
se hai un'idea che ti piace e che calza proponila ;-)



> Non solo si possono, bensi' si *devono*

Non mancherò di guardare il video nelle prox settimane

l'uso che ho fatto del termine data-flow è quello classico secondo la tassonomia di Flynn e è circoscritto ad architetture HW a stream multiplo di dati , una architettura distinta e da quella di von newman/control-flow

in questo ciclo di post mi limito a raccogliere idee/pattern per il control-flow

per capire il modo in cui hai inteso data-flow credo dovrò prima vedermi il video
  
Gravatar # re: Progettazione di applicazioni multi-threading
by LudovicoVan at 16/05/2008 1.47

> > No, quella liberta' non ce la possiamo prendere. Cosa dice l'analisi dei requisiti e dei constraint?

> parti dalla descrizione del servizio erogato dal sw che è chiara.
> se hai un'idea che ti piace e che calza proponila ;-)

Scusa ma non ti seguo. Al dunque, abbiamo completato la fase di analisi (del problema), dopodiche' **non** segue la produzione (della soluzione), segue l'atto di decisione manageriale sul "si fa o non si fa, e se si fa, a che condizioni". Io non ho idee da proporre, ne' idee che mi piacciono in astratto. Analisi di solito la faccio gratis, comunque, per diversi e tutti ovvi motivi. Se poi decidi che vuoi procedere all'intervento, al limite mi puoi affidare l'incarico. (Posta la domanda, si puo' cominciare a parlare di soluzioni.)

> > Non solo si possono, bensi' si *devono*

> Non mancherò di guardare il video nelle prox settimane

> l'uso che ho fatto del termine data-flow è quello classico secondo la tassonomia di Flynn e è circoscritto ad architetture HW a stream multiplo di dati , una architettura distinta e da quella di von newman/control-flow

Non conosco la tassonomia di Flynn. Ti posso pero' gia' dire che nei modelli che ho studiato, e' l'analisi del flusso dei dati ad essere basilare; su di essa si construisce eventualmente un'analisi del flusso funzionale; ed e' solo con i sistemi real-time e/o critici che si arriva all'analisi del flusso del controllo.

> in questo ciclo di post mi limito a raccogliere idee/pattern per il control-flow

Il mio pattern di riferimento, come ti accennavo, e' la macchina a stati, che e' appunto la macchina di Turing (non di Von Neumann), che e' appunto la formalizzazione di una macchina algoritmica, che e' appunto la formalizzazione del paradigma imperativo.

Il paradigma funzionale e' invece esemplificato dai linguaggi funzionali/dichiarativi, e' il calcolo lambda di Church, ed e' equivalente alla macchina di Turing (i due approcci si incontrano a meta strada: cfr. il discorso su F# nel video) ma forse solo appunto nell'ambito dell'Universo di Von Neumann, che e' il dominio della trattabilita'/computabilita' nel suo complesso.

> per capire il modo in cui hai inteso data-flow credo dovrò prima vedermi il video

E' sicuramente una buona introduzione.

-LV
  
Gravatar # re: Progettazione di applicazioni multi-threading
by Luca Minudel at 16/05/2008 2.08

> Scusa ma non ti seguo. Al dunque, abbiamo completato la fase di analisi ...

siamo seduti in torno a un tavolo, ci sono delle CRC con resposnabilità e relazioni tra le classi e un bug noto - se c'è un'idea x risolverlo migliorando il disegno si propone

è un atto creativo tra geeks - semplice e informale

> Non conosco la tassonomia di Flynn.

ah ok ora mie è chiaro - diciamo data-flow e stiamo parlando di 2 cose differenti (Flynn's taxonomy con google x scoprire quello che intendevo)
  
Gravatar # re: Progettazione di applicazioni multi-threading
by LudovicoVan at 16/05/2008 2.31

> > Scusa ma non ti seguo. Al dunque, abbiamo completato la fase di analisi ...

> siamo seduti in torno a un tavolo, ci sono delle CRC con resposnabilità e relazioni tra le classi e un bug noto - se c'è un'idea x risolverlo migliorando il disegno si propone

Quindi mi hai gia' assunto?

> è un atto creativo tra geeks - semplice e informale

Dipende. Dalle premesse.

> > Non conosco la tassonomia di Flynn.

> ah ok ora mie è chiaro - diciamo data-flow e stiamo parlando di 2 cose differenti (Flynn's taxonomy con google x scoprire quello che intendevo)

Non manchero', serio.

-LV
  

Your comment:

Title:
Name:
Email:
Website:
 
Italic Underline Blockquote Hyperlink
 
 
Please add 5 and 6 and type the answer here: