Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1

    [Delphi], Critical Section

    Mi serve il parere di una persona che ne sa davvero, non capisco cosa sto sbagliando o comunque cosa sta succedendo. Volevo mettere un post su http://www.delphiedintorni.it ma oggi non funziona.

    Ho un'applicazione multithread che tra le varie cose scrive su un file di testo ciò che accade. La procedura
    che scrive sul file è sottoposta a CriticalSection di modo che i threads non aprano contemposaneamente il file di log insieme.
    A volte capita (tipo una volta al mese) che un thread venga tenuto bloccato dalla CriticalSection a lungo, oggi addirittura per 20 minuti. Poi scrive ciò che deve e prosegue il suo lavoro come nulla fosse. Il fatto è che in quei 20 minuti comunque gli altri threads hanno eseguito la procedura correttamente per cui la CriticalSection non era bloccata ma è stato il thread a non accorgersi di quando la procedura si è liberata.
    Può essere che il sistema operativo sospenda l'esecuzione di un thread quando è oberato di lavoro proprio quando il thread incontra una CriticalSection bloccata?

    Io uso le CriticalSection così:

    codice:
    ...OnCreate()
    	InitializeCriticalSection(TCSLog);
    	...
    
    
    procedure .....
    begin
    	EnterCriticalSection(TCSLog);
    	...
    	...
    	LeaveCriticalSection(TCSLog);
    end;

  2. #2
    Non sarò di grande aiuto, ma spero di darti qualche idea.

    Prima cosa: come mai non utilizzi la classe TCriticalSection?

    Secondo, anche se ovviamente non è questo che causa il problema da te descritto, il codice tra EnterCriticalSection e LeaveCriticalSection è protetto da eventuali eccezioni vero?

    Infine, i thread che utilizzano la classe per generare il LOG hanno almeno una Sleep nel loro ciclo? Sono TThread o li crei in altro modo?

    HTH,

  3. #3
    TCSLog è un oggetto TCriticalSection
    Il programma è pieno di cicli try Except.

    Il programma

    codice:
    var
      TSNTPServer: TIdSNTP;
      TDTOraInternet: TDateTime;
    begin
      SincLog(NomeFile, 'SorgenteDataOra()'); // Riga 1
      if Base.SincroniaSNTP then begin // era false
      end else begin
        TDTOraInternet:= Now;
        DateTime:= IncMinute(TDTOraInternet, TimeDelay); // TimeDelay era 0
        SincLog(NomeFile, 'Uso DateTime dal Server locale -> '+ DateTimeToStr(TDTOraInternet, MySettings)+ '. Incremento di minuti: '+ IntToStr(TimeDelay)+ ', ottengo: -> '+ DateTimeToStr(DateTime, MySettings)); // Riga 2
        ...
      end;
    ha impiegato 20 minuti per andare dalla riga 1 alla riga 2, se pur eseguendo perfettamente il codice. La procedura che contiene la CriticalSection si chiama SincLog();

    Non so cosa fare, il programma comunque cammina per mesi è che a volte si comporta così.

  4. #4
    TCSLog è un oggetto TCriticalSection
    Allora non capisco perchè non usi i relativi metodi Enter e Leave.

    Il programma è pieno di cicli try Except.
    In questo caso mi riferivo ovviamente al codice protetto dalla critical section.

    La procedura che contiene la CriticalSection si chiama SincLog();
    Giusto per conferma: la critical section comunque è allocata fuori dalla SincLog vero?

    Come tu stesso dicevi, è probabile che non sia la critical section a bloccare quel thread. E nel codice che hai postato mi pare che l'unica cosa su cui indagare sia Base.SincroniaSNTP.

    HTH,

  5. #5
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,288
    Direi che sono stati forniti già ottimi suggerimenti, quindi aggiungo solo un paio di considerazioni al problema.

    La protezione del codice nella critical section va fatta usando try...finally:

    codice:
    EnterCriticalSection(TCSLog);
    try
    	...
    	...
    finally
      LeaveCriticalSection(TCSLog);
    end;
    Questo garantisce che l'oggetto venga rilasciato anche in caso di errori, impedendo un "deadlock" dell'applicazione.

    In merito al problema specifico, credo che ci sia da indagare maggiormente sulle operazioni svolte dal programma per saperne di più: il ritardo potrebbe essere dovuto a qualcosa che non è strettamente legato al multithreading.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  6. #6
    La protezione del codice nella critical section va fatta usando try...finally:
    Non necessariamente. Va bene anche un Try...Except nel qual caso ovviamente la critical section va sbloccata dopo il blocco Except.

  7. #7
    Tutto vero per carità ma la cosa non mi aiuta.
    Ribadisco che errori non ne vengono dati, il programma alla chiusura non segnala alcun memory leak e quant'altro.

  8. #8
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,288
    Originariamente inviato da ESSE-EFFE
    Non necessariamente. Va bene anche un Try...Except nel qual caso ovviamente la critical section va sbloccata dopo il blocco Except.
    In questo caso, può andare bene; in generale, non si tratta dello scopo specifico del "try...except", poiché

    1)
    è il costrutto "try...finally" ad esprimere, in generale, il concetto "qualunque cosa succeda, fai...";

    2)
    all'atto pratico, non è possibile inserire un raise nel blocco di gestione dell'eccezione senza modificare il codice restante, poiché in questo caso il rilascio della CriticalSection non verrebbe eseguita;

    3)
    usando la "try...except", è obbligatorio occuparsi logicamente e fattivamente della gestione dell'errore, cosa che non sempre è voluta o si vuole affrontare (o almeno, non in quella sede specifica, ma magari in un punto superiore del "call stack").

    In breve, usare sempre il costrutto "try...except" per garantire il rilascio di risorse è fuorviante: serve per la gestione degli errori, quindi va inserito solo se si intende farla in questo contesto, lasciando al blocco "try...finally" il compito di racchiudere e separare i blocchi protetti di codice da quelli preposti al rilascio delle risorse allocate, indipendentemente dalla presenza - o meno - di codice per la gestione degli errori, che potrebbe anche non essere presente.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  9. #9
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,288
    Originariamente inviato da denis76
    Ribadisco che errori non ne vengono dati, il programma alla chiusura non segnala alcun memory leak e quant'altro.
    Con quale strumento hai verificato la mancanza di memory leak?
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  10. #10
    EurekaLog 6.0.17 su BDS 2006

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.