Uso di thread

I nodi di elaborazione dei messaggi ed i programmi di analisi devono operare in un ambiente a più thread e più istanze. Possono essere presenti molti oggetti nodi o programmi di analisi, ognuno con molti elementi di sintassi, e possono essere presenti molti thread che eseguono metodi su tali oggetti. La struttura del broker dei messaggi assicura che un oggetto messaggio e gli eventuali oggetti di sua proprietà vengano utilizzati solo dal thread che riceve ed elabora il messaggio attraverso il flusso di messaggi.

Un'istanza di un nodo di elaborazione del flusso di messaggi viene condiviso ed utilizzato da tutti i thread che servono il flusso di messaggi in cui è definito il nodo. Relativamente ai programmi di analisi, un'istanza di un programma di analisi viene utilizzata solo da un unico thread di flusso di messaggi.

Un'estensione definita da un utente deve aderire a tale modello e deve evitare l'uso di dati globali o risorse che richiedono semafori per serializzare l'accesso ai thread. Tale serializzazione può risultare in colli di bottiglia delle prestazioni.

Le funzioni di implementazione dell'estensione definita dall'utente devono essere rientranti e così anche le eventuali funzioni che queste richiamano. Tutte le funzioni di utilità dell'estensione definita dall'utente sono completamente rientranti.

Sebbene un'estensione definita dall'utente può produrre ulteriori thread se richiesto, è essenziale che lo stesso thread restituisca il controllo al broker al completamento di una funzione di implementazione. Nell'eventualità si verifichi un malfunzionamento nell'esecuzione di ciò, verrà compromessa l'integrità del broker e si verificheranno dei risultati imprevedibili.

Modello di esecuzione

Quando viene inizializzato un gruppo di esecuzione, le LIL appropriate vengono messe a disposizione del runtime. Viene avviata l'elaborazione di runtime del gruppo di esecuzione e viene prodotto un thread di configurazione dedicato. Nell'ambiente di esecuzione del flusso di messaggi, tale flusso è thread-safe. E' possibile eseguire contemporaneamente flussi di messaggi su molti thread OS, senza dover considerare questioni di serializzazione. I nodi definiti dall'utente che vengono implementati non devono compromettere tale modello di thread. Tenere presenti i seguenti punti:
  • Un messaggio di input inviato ad un flusso di messaggi viene elaborato solo dal thread che lo riceve. Durante l'elaborazione del messaggio non ha luogo alcun cambiamento di contesto o di thread.
  • Le strutture di dati a cui accedono i flussi di messaggi sono visibili solo ad un unico thread e tali strutture di dati esistono solo per la durata dell'elaborazione del messaggio.
  • Una sola istanza di un flusso di messaggi viene condivisa tra tutti i thread nel pool di thread del flusso di messaggi. Ciò è correlato al funzionamento di un nodo flusso di messaggi in quanto non ha uno stato.
  • I requisiti di memoria di un gruppo di esecuzione non sono eccessivamente interessati dai flussi di messaggi in esecuzione su più thread OS.

Modello di thread

L'esempio di flusso di messaggi riportato di seguito risulta utile nella comprensione di alcune delle considerazioni di thread che devono essere tenute presenti quando di progettano e implementano propri nodi definiti dall'utente. Viene considerato l'esempio di un nodo di input definito dall'utente.

E' possibile configurare un flusso di messaggi da eseguire su una serie di thread. Ciò è determinato dal numero di nodi di input nel flusso di messaggi e dal valore della proprietà additionalInstances del flusso di messaggi. Questi due elementi determinano la capacità massima del pool di thread che il flusso di messaggi può utilizzare. Quindi, se il flusso di messaggi ha determinati requisiti di elaborazione che richiedono l'esecuzione di un singolo thread, è necessario assicurare che questo sia il caso.

Di seguito è riportato un tipico ordine di eventi per l'elaborazione di un nodo di input:
  1. Viene eseguita la creazione di un nodo di input
  2. Il pool di thread richiede un thread
  3. Il thread assegnato viene avviato nel metodo di esecuzione del nodo
  4. Viene eseguito il commit della configurazione (o riconfigurazione)
  5. Viene eseguita l'elaborazione dell'inizializzazione sul contenuto del thread
  6. Il thread esegue il collegamento al gestore code del broker
  7. Vengono creati un gruppo di messaggi e un oggetto buffer
  8. Una richiesta queue open per la coda di input viene inviata al gestore code. Tale coda viene tenuta aperta per la durata del thread.
  9. Il nodo di input immettere un loop di elaborazione messaggi
  10. Quando viene ricevuto un messaggio, il buffer dei dati contiene l'intestazione e il contenuto del messaggio
  11. Oggetti messaggio vengono creati e collegati al gruppo del thread
  12. L'invio dei thread viene attivato se sono specificati più thread
  13. I dati del messaggio vengono propagati.
E' necessario tenere presente quanto segue:
  • Il nodo di input implementerà il modello di thread del flusso di messaggi scelto.
  • Il nodo di input avrà sempre almeno un thread che esegue la lettura dalla relativa origine di input o che attivamente elabora un messaggio ricevuto da questi. Se un flusso di messaggi ha più nodi di input, allora sono disponibili ulteriori istanze di thread per servire i nodi di input, come stabilito dalla politica di invio di tale nodo di input .
E' possibile eseguire domande o richieste ai thread. Quando il flusso di messaggi viene distribuito, il nodo di input richiede un thread iniziale. Sebbene al flusso di messaggi è associato un pool di thread, è il nodo di input che è responsabile della politica di invio. Ciò significa che deve garantire sempre che su un thread sia in esecuzione una sua istanza. Poiché il valore predefinito della proprietà additionalInstances è zero, ogni ulteriore richiesta per un thread non avrà esito positivo se sono stati definiti più nodi di input. Ciò significa che è possibile per un flusso di messaggi consumare più thread di quelli previsti. Inoltre, ciò potrebbe significare che se sono stati definiti più nodi di input, uno di questi potrebbe non avere thread sufficienti.

Il modo più efficace per impedire alla coda di input di diventare un collo di bottiglia consiste nel consentire al broker di avviare ulteriori copie del flusso di messaggi in thread separati utilizzando la proprietà additionalInstances. Tuttavia, la creazione di thread separati consente l'elaborazione parallela di messaggi dal gestore code, cosicché è necessario utilizzare solo questa proprietà quando l'ordine di elaborazione dei messaggi non è importante.

I thread vengono creati come risultato del funzionamento e della creazione del nodo di input. Un thread rimane attivo o inattivo nel pool di thread e i thread inattivi rimangono nel pool finché non vengono inviati da un nodo di input o il broker non viene chiuso.

La figura riportata di seguito mostra l'assegnazione di thread in un flusso di messaggi.

Assegnazione di thread in un flusso di messaggi


Fare riferimento al testo di accompagnamento per una spiegazione degli elementi nel diagramma

Inizialmente, viene eseguita una domanda al Thread 1 (A) quindi attende messaggi. Quando arriva un messaggio (B), il Thread 1 propaga il messaggio e invia il Thread 2. Il Thread 2 riceve immediatamente un messaggio (C) e propaga e invia il Thread 3, che attende un messaggio (D). Il Thread 1 termina (E) e torna al pool di thread. Il Thread 3 riceve quindi un messaggio (F), invia il Thread 1 e propaga il messaggio. Il Thread 1 attende quindi l'arrivo di un messaggio sulla coda (G).

Degno di nota è il punto contrassegnato con H. A questa istanza nel flusso di messaggi, il Thread 1 acquisisce un messaggio, ma poiché tutti gli altri thread sono attivi in quel momento, non può eseguire l'invio. Il messaggio viene propagato.

Dopo che questo messaggio è stato propagato, il Thread 2 termina (I), riceve un nuovo messaggio dalla coda e ne esegue la propagazione. Il Thread 3 quindi termina (J) e torna al pool. Quindi anche il Thread 2 termina (K). Poiché non ha eseguito l'invio, quando il Thread 1 termina (L), non può tornare al pool di thread anche se non ci sono messaggi nella coda; attende quindi l'arrivo di un messaggio sulla coda.

Tenere presenti i seguenti punti relativi al funzionamento del thread in WebSphere Message Broker:
  • I thread vengono creati solo se richiesto dal carico di lavoro. Ciò significa che un'elaborazione del gruppo di esecuzione può utilizzare meno thread di quelli di cui è stata eseguita la configurazione.
  • A meno che tutti i thread disponibili non sono effettivamente in elaborazione all'interno di un flusso di messaggi, un thread eseguirà sempre la lettura della coda di input.
  • Se il carico di lavoro aumenta in un punto qualsiasi, altri nodi di input nello stesso flusso di messaggi saranno in grado di acquisire thread che sono stati restituiti al pool di thread.
Se un thread acquisisce un messaggio, ma tutti gli altri thread sono attivi in tale fase, non può eseguire l'invio. Il messaggio viene propagato. Quando questo thread termina, in quanto non ha eseguito l'invio, non può tornare al pool di thread anche se non ci sono messaggi sulla coda.
Riferimenti correlati
cniDispatchThread
Informazioni particolari | Marchi | Download | Libreria | Supporto | Commenti
Copyright IBM Corporation 1999, 2006 Ultimo aggiornamento: ago 17, 2006
as01460_