PDA

Visualizza la versione completa : [DELPHI] Stato di una Critical Section


denis76
20-12-2007, 14:29
E' possibile sapere se una CriticalSection è nello stato Leave?

alka
22-12-2007, 17:00
So che non è bello rispondere con una domanda, ma siccome non mi è mai capitato di avere una simile esigenza, ero curioso di sapere... a cosa serve determinare lo stato di una Critical Section? :master:

denis76
22-12-2007, 17:24
Spiego.
Conosco poco Delphi e mi sono trovato a dover scrivere un programma multithread che controlla dei dispositivi via rete.
Quando un client si collega al programma il programma genera un thread per gestire il client. Può accadere che per qualche motivo il client si scolleghi o divenga irraggiungibile anche se il thread non ha ancora terminato il dialogo. In questi casi il più delle volte riesco a gestire la cosa in altri può accadere che il thread si pianti e che quindi tenga bloccata una CriticalSection.
Ora non sto usando le CriticalSection ma uso delle variabili booleane. Mi segno inoltre il momento in cui le funzioni che sono accessibili in modalità multithread vengono invocate. Se tali funzioni rimangono bloccate a lungo le sblocco io in modo forzato.
Il programma è un servizio che rimane sempre attivo e che in una settimana gestisce 1000 - 2000 connessioni. Senza questo sistema strampalato di gestire le cose è sufficiente che un thread non liberi una funzione che tutto si blocca.

Credo sia evidente che sono un novellino in materia ma ai clienti non si può certo dire di no.

Come gestiresti la cosa tu?

alka
22-12-2007, 18:14
Non sono certo di aver ben compreso la problematica che devi gestire, ad ogni modo posso solo dire che non comprendo come una Critical Section possa mantenere bloccato un intero sistema.

Mi spiego: l'uso di una CS è limitato al momento in cui vi sono thread che fanno uso di risorse condivise, per impedire che l'accesso asincrono a queste ultime possa comprometterne lo stato lasciandolo "intermedio" o modificando quello che ciascun thread si aspetta di trovare nel momento in cui inizia a lavorarci sopra.

Non comprendo come sia possibile che i thread in esame rimangano bloccati all'interno di una Critical Section.

Quando si accede ad una CS, occorre sempre usare un costrutto try...finally per garantire che, qualunque cosa succeda, tale sezione venga rilasciata al termine.

L'accesso ad una CS, inoltre, dovrebbe essere "istantaneo", cioè legato ad un'operazione che lavora sui dati a cui accedono potenzialmente uno o più thread, per impedire che questi possano leggere o scrivere informazioni che sono "in uso", provvedendo a liberarle non appena l'operazione in questione è terminata, e per "operazione" mi riferisco ad una sequenza finita e ben precisa di istruzioni.

Dato questo panorama, mi riesce difficile comprendere come sia possibile ottenere dei blocchi lunghi dei thread, o delle problematiche per le quali si debba verificare lo stato, o addirittura liberarlo (operazione che farebbe cadere le garanzie offerte appunto dalle CS in ambito multithreading).

Ipotizzo quindi che il problema sia dovuto ad un errato uso delle CS, o più in generale ad un'organizzazione errata del sistema. Tali strumenti gestiti da Delphi, comunque, sono presenti in altre forme diverse ma dal comportamento analogo anche in altri linguaggi e architetture (es. NET Framework).

Forse si dovrebbe approfondire meglio la programmazione multithreading con qualche ricerca o documentazione specifica.

Ciao! :ciauz:

denis76
22-12-2007, 18:52
Nell'applicazione di cui stiamo parlando faccio uso di un oggetto TIdTcpServer ed un oggetto TIdHTTPServer. In particolare quest'ultimo genera un thread ogni qualvolta un client esegue un POST. Sono praticamente certo che se il thread generato dall'oggetto TIdHTTPServer deve eseguire un'operazione lunga (query, ...) esso viene interrotto.


Ad ogni modo:

E' corretto affermare che in un blocco try - finally, qualunque cosa accada al thread che sta eseguendo il codice contenuto nel blocco try viene comunque eseguita la parte contenuta nel blocco finally?

Se un thread esegue EnterCriticalSection(...) e muore la CriticalSection passa nello stato Leave in modo automatico oppure no?

Come fai a mandare informazioni tra thread? Usi PostMessage?

Loading