Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Le soluzioni FSP per il 2026: potenza e IA al centro
Le soluzioni FSP per il 2026: potenza e IA al centro
In occasione del Tech Tour 2025 della European Hardware Association abbiamo incontrato a Taiwan FSP, azienda impegnata nella produzione di alimentatori, chassis e soluzioni di raffreddamento tanto per clienti OEM come a proprio marchio. Potenze sempre più elevate negli alimentatori per far fronte alle necessità delle elaborazioni di intelligenza artificiale.
AWS annuncia European Sovereign Cloud, il cloud sovrano per convincere l'Europa
AWS annuncia European Sovereign Cloud, il cloud sovrano per convincere l'Europa
AWS è il principale operatore di servizi cloud al mondo e da tempo parla delle misure che mette in atto per garantire una maggiore sovranità alle organizzazioni europee. L'azienda ha ora lanciato AWS European Sovereign Cloud, una soluzione specificamente progettata per essere separata e distinta dal cloud "normale" e offrire maggiori tutele e garanzie di sovranità
Redmi Note 15 Pro+ 5G: autonomia monstre e display luminoso, ma il prezzo è alto
Redmi Note 15 Pro+ 5G: autonomia monstre e display luminoso, ma il prezzo è alto
Xiaomi ha portato sul mercato internazionale la nuova serie Redmi Note, che rappresenta spesso una delle migliori scelte per chi non vuole spendere molto. Il modello 15 Pro+ punta tutto su una batteria capiente e su un ampio display luminoso, sacrificando qualcosa in termini di potenza bruta e velocità di ricarica
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 12-07-2011, 10:24   #1
agosteeno
Member
 
Iscritto dal: Aug 2009
Messaggi: 119
[C] [risolto] terminazione pulita di un server multithread

Salve a tutti ho una questione da sottoporvi, per avere qualche consiglio. Per un esame ho un server multithread. La terminazione dell'esecuzione deve avvenire tramite il trattamento del segnale SIGINT e SIGTERM. Il problema nasce dal fatto che quando si chiede di terminare l'esecuzione, si devono terminare tutte le operazioni in coda richieste dai vari client (per ognuno dei quali c'e' un thread apposito che lo serve) piu' un thread particolare che si attiva ogni tot secondi e serve tutte le richieste in coda. Quando arriva una di questi segnali questo thread dovrebbe iniziare la sua esecuzione, soddisfare le ultime richieste in coda e poi chiudere il server in maniera pulita (quindi chiudere la socket, chiudere file aperti e cose del genere). Questo thread a regime esegue un ciclo infinito e una sleep di tot secondi per regolare la temporizzazione. Il trattamento dei segnali e' gestito installando dei gestori, tramite una funzione particolare. Come potrei sistemare il gestore di SIGINT e SIGTERM per fare in modo che il thread si renda conto che nn ha semplicemente eseguito una sleep e quindi possa terminare il ciclo infinito e terminare il server?

Ultima modifica di agosteeno : 02-09-2011 alle 11:50. Motivo: problema risolto
agosteeno è offline   Rispondi citando il messaggio o parte di esso
Old 12-07-2011, 11:46   #2
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 12923
Cosa fai di preciso all'interno del ciclo in cui è inserita la sleep?

Potresti pensare di impostare opportunamente una variabile globale all'arrivo del segnale in questione, ad esempio un booleano.

Codice:
..

bool Run = TRUE;

while ( Run )
{
    // codice con sleep
}

/* Cleanup */
..
All'arrivo del segnale specificato Run viene posta a FALSE, così al successivo ciclo utile il while termina e puoi eseguire la cleanup.
WarDuck è offline   Rispondi citando il messaggio o parte di esso
Old 12-07-2011, 11:57   #3
agosteeno
Member
 
Iscritto dal: Aug 2009
Messaggi: 119
Grazie per la risposta. Allora, nel codice della sleep il thread esegue sostanzialemente le operazioni chieste dal client. Nel mio caso particolare si tratta di un server che gestisce richieste e offerte di carsharing. Il problema pero' nn e' solo questo. Mi spiego meglio: il thread in questione ha un ciclo infinito e avevo gia' pensato si risolverlo in una maniera simile a come hai suggerito. Il fatto e' che anche il main esegue un ciclo infinito nel quale esegue una accept per accettare nuovi client e dunque dovrei terminare anche il suo ciclo. La variabile potrebbe essere globale nel senso che potrei usarla sia sul ciclo del main che del thread particolare? La cleanup la farebbe direttamente il thread che esegue le operazioni in modo tale da essere sicuro da soddisfare tutte le richieste pendenti...
agosteeno è offline   Rispondi citando il messaggio o parte di esso
Old 12-07-2011, 12:04   #4
agosteeno
Member
 
Iscritto dal: Aug 2009
Messaggi: 119
Tra l'altro ripensandoci potrei, invece di chiamare la pthread_detach appena creo il thread particolare, chiamare dal main la pthread_join quando esco dal ciclo, in modo da poter garantire la corretta terminazione. Infatti se nn sbaglio all'uscita del main dovrebbe terminare tutto il processo.
agosteeno è offline   Rispondi citando il messaggio o parte di esso
Old 12-07-2011, 12:22   #5
agosteeno
Member
 
Iscritto dal: Aug 2009
Messaggi: 119
Piccolo problema: per il main nn posso usare questa soluzione perche' in realta' lui e' bloccato sulla accept. Di conseguenza dovrebbe per lo meno accettare una nuova richiesta e poi all'iterazione successiva, quando ricontrolla la variabile uscirebbe dal ciclo. Ma questo non e' il comportamento che voglio. Senza contare il fatto che questa richiesta potrebbe nn arrivare mai e dunque il server non terminare...
agosteeno è offline   Rispondi citando il messaggio o parte di esso
Old 12-07-2011, 13:33   #6
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 12923
Relativamente alla accept

Se non ricordo male alla ricezione dei segnali alcune chiamate a funzione possono terminare.

Per evitare ciò ci sono due modi, uno è mascherare i segnali, mentre l'altro è semplicemente riavviare la funzione (credo ci sia un flag da passare da qualche parte).

Ora non ricordo esattamente i dettagli di questa cosa, però potresti sfruttare questo comportamento per la accept (che a quel punto terminerebbe e dunque il ciclo verrebbe sbloccato).

Una alternativa a questa cosa potrebbe essere effettuare una connessione locale al server e mandare un messaggio preciso di chiusura.

Edit

Ho trovato:

http://linux.die.net/man/2/sigaction

Mi ricordavo bene, il flag SA_RESTART ti consente di far ripartire la funzione.

Se tu prepari un handler separato per i segnali che ti interessano e chiami questa funzione senza passargli il flag SA_RESTART, alla ricezione dei segnali le chiamate in attesa dovrebbero terminare.

Ultima modifica di WarDuck : 12-07-2011 alle 13:43.
WarDuck è offline   Rispondi citando il messaggio o parte di esso
Old 12-07-2011, 14:34   #7
agosteeno
Member
 
Iscritto dal: Aug 2009
Messaggi: 119
Devo giusto precisare che si tratta di un client server gia' locale. Locale nel senso che le socket usate sono le AF_UNIX. Si tratta di un progetto per il laboratorio di sistemi operativi. Non ho ben capito come dovrebbe funzionare il flag sa_restart: in pratica con un handler nel quale modifico una variabile (in questo caso particolare) basterebbe a risolvere la situazione perche' le chiamate che sono in attesa verrebbero sbloccate?
agosteeno è offline   Rispondi citando il messaggio o parte di esso
Old 12-07-2011, 17:55   #8
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 12923
Quote:
Originariamente inviato da agosteeno Guarda i messaggi
Devo giusto precisare che si tratta di un client server gia' locale. Locale nel senso che le socket usate sono le AF_UNIX. Si tratta di un progetto per il laboratorio di sistemi operativi. Non ho ben capito come dovrebbe funzionare il flag sa_restart: in pratica con un handler nel quale modifico una variabile (in questo caso particolare) basterebbe a risolvere la situazione perche' le chiamate che sono in attesa verrebbero sbloccate?
Di default alla ricezione di un segnale alcune chiamate di sistema vengono interrotte (dunque falliscono e riportano codice di errore EINT), quel flag serve per farle ripartire.

In genere può essere comodo farle ripartire quando devi gestire segnali custom tipo SIGUSR1 e SIGUSR2.

Nel tuo caso però vuoi avere il comportamento di default, con le funzioni che vengono interrotte alla ricezione di un segnale.

Ultima modifica di WarDuck : 12-07-2011 alle 17:59.
WarDuck è offline   Rispondi citando il messaggio o parte di esso
Old 12-07-2011, 18:00   #9
agosteeno
Member
 
Iscritto dal: Aug 2009
Messaggi: 119
Lavorandoci su mi sono reso conto che sostanzialmente interrompe la funzione. Quindi ho fatto cosi': controllo il valore restituito. Se = -1 allora significa che la accept e' stata interrotta bruscamente. Faccio un break ed esco dal ciclo. A questo punto controllo il valore della variabile globale (ho visto che devo definirla di tipo volatile sig_atomic_t): se ha il valore dato dal gestore (che poi e' anche quello che serve per far terminare il while del thread che esegue le altre operazioni) allora significa che si tratta di una terminazione gentile. Quindi faccio la join su questo thread e lui eseguira' la pulizia. Altrimenti si tratta di una situazione anomala e vedro' di trattarla di conseguenza. Per ora sembra andare bene, per lo mena pare faccia quello che voglio io.
agosteeno è offline   Rispondi citando il messaggio o parte di esso
Old 13-07-2011, 09:53   #10
WarDuck
Senior Member
 
L'Avatar di WarDuck
 
Iscritto dal: May 2001
Messaggi: 12923
Quote:
Originariamente inviato da agosteeno Guarda i messaggi
Lavorandoci su mi sono reso conto che sostanzialmente interrompe la funzione. Quindi ho fatto cosi': controllo il valore restituito. Se = -1 allora significa che la accept e' stata interrotta bruscamente. Faccio un break ed esco dal ciclo. A questo punto controllo il valore della variabile globale (ho visto che devo definirla di tipo volatile sig_atomic_t): se ha il valore dato dal gestore (che poi e' anche quello che serve per far terminare il while del thread che esegue le altre operazioni) allora significa che si tratta di una terminazione gentile. Quindi faccio la join su questo thread e lui eseguira' la pulizia. Altrimenti si tratta di una situazione anomala e vedro' di trattarla di conseguenza. Per ora sembra andare bene, per lo mena pare faccia quello che voglio io.
Senza usare break:

Codice:
while ( accept(..) >= 0 )
{
   ...
}

/* Codice di cleanup */
Relativamente al cleanup, immagino che ogni thread abbia il suo insieme di risorse da liberare, come la gestisci questa cosa?

Riguardo alle variabili globali bisogna vedere quanti thread vogliono accedere a quella variabile e come questa variabile viene modificata dal gestore del segnale.

Se la catena degli eventi è strettamente:
- ricezione segnale
- gestione tramite sighandler
- terminazione accept

Allora non dovresti aver bisogno di accorgimenti particolari, perché quando termina accept sei sicuro che Run è cambiata e vi accedi quando nessun'altro più può cambiarla (per stare sicuro puoi mascherare a quel punto l'arrivo di nuovi segnali, anche se non dovrebbe essere necessario).

.

Ultima modifica di WarDuck : 13-07-2011 alle 09:55.
WarDuck è offline   Rispondi citando il messaggio o parte di esso
Old 13-07-2011, 10:15   #11
agosteeno
Member
 
Iscritto dal: Aug 2009
Messaggi: 119
Grazie per il consiglio sul break, tanto semplice ma nella fretta nn mi e' venuto in mente! Riguardo alla variabile globale verra' usata solo da 2 diversi thread in lettura e in scrittura solo dall'handler, quindi nn dovrebbe dare problemi. Per quanto riguarda le risorse che devono liberare gli altri thread ancora nn ho ben deciso anche perche' a parte il fatto di avere una connessione attiva con i client (che nn e' un dettaglio da poco) devono effettuare solo le eventuali free del caso. Anche gli altri thread cmq hanno un ciclo al loro interno, all'interno del quale ascoltano le varie richieste dei client. Usero' anche per loro un meccanismo simile a quello detto fin'ora, considerando il fatto che in realta' le risposte ai client le invia il thread di cui parlavo nei post precedenti.
agosteeno è offline   Rispondi citando il messaggio o parte di esso
Old 31-08-2011, 12:29   #12
agosteeno
Member
 
Iscritto dal: Aug 2009
Messaggi: 119
Salve, riprendo questa discussione perche' si tratta sempre della stessa problematica.

La situazione attuale e' questa: quando effettuo un ctrl-c il server deve terminare gentilmente e questo verra' fatto da un thread che di base effettua un altro compito, ma al suo interno ha un ciclo, la cui condizione viene cambiata dal gestore del SIGINT per fare in modo che quando viene gestito esca dal ciclo ed effettui le operazioni del caso. Il main e' bloccato sulla accept perche' il suo compito e accettare nuove connessioni da parte di client (la accept e' anche la condizione del while: while ((canale = accept(socket)) >= 0)). All'uscita di questo while c'e' l'attesa per la terminazione del thread di prima (pthread_join) piu' altre operazioni del caso.
In teoria, quando il server riceve il SIGINT, siccome il main era bloccato in attesa sulla accept (in realta' si tratta di una mia funzioncina che chiama la accept, ma e' sostanzialmente identica ad una accept normale) dovrebbe sbloccarsi, restituire -1 aggiornando il valore di errno a EINTR e dunque causare l'uscita dal ciclo. Questo pero' non avviene e non riesco a capire per quale motivo. In pratica rimane bloccato (nel senso che la accept non restituisce nessun valore) ma non accetta neanche nuove connessioni e dunque e' chiaro che la ricezione del segnale ha avuto un qualche effetto.
Per la gestione dei segnali ho un file particolare che implementa una funzione che carica i gestori dei segnali interessati, tra cui il SIGINT e nn mi sembra ci siano maschere attive o flag settati.
Qualcuno ha idea di quale possa essere il problema?
agosteeno è offline   Rispondi citando il messaggio o parte di esso
Old 02-09-2011, 11:49   #13
agosteeno
Member
 
Iscritto dal: Aug 2009
Messaggi: 119
Ok, problema risolto! Il problema era un cattivo uso delle maschere per i segnali. Oltretutto nella funzione che installa i gestori mi dimenticavo di disabilitare la maschera. Almento il tutto mi e' servito per capire bene come funziona i segnali! Grazie a tutti
agosteeno è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Le soluzioni FSP per il 2026: potenza e IA al centro Le soluzioni FSP per il 2026: potenza e IA al ce...
AWS annuncia European Sovereign Cloud, il cloud sovrano per convincere l'Europa AWS annuncia European Sovereign Cloud, il cloud ...
Redmi Note 15 Pro+ 5G: autonomia monstre e display luminoso, ma il prezzo è alto Redmi Note 15 Pro+ 5G: autonomia monstre e displ...
HONOR Magic 8 Pro: ecco il primo TOP del 2026! La recensione HONOR Magic 8 Pro: ecco il primo TOP del 2026! L...
Insta360 Link 2 Pro e 2C Pro: le webcam 4K che ti seguono, anche con gimbal integrata Insta360 Link 2 Pro e 2C Pro: le webcam 4K che t...
Compra una GeForce RTX 5080 venduta e sp...
Telescopio spaziale James Webb: osservat...
L'IA non ha portato quasi nessun benefic...
Sony LinkBuds Clip, gli auricolari open ...
La fibra è sempre più diff...
Arriva Vertiv CoolPhase PAM: raffreddame...
Chiamate cristalline e ANC evoluto a pre...
Adobe aggiorna Premiere e After Effects:...
AI Bundle, la novità dei driver A...
La roadster elettrica supportata da Xiao...
Netflix rivede l'offerta per Warner Bros...
Satya Nadella avverte: senza benefici co...
Anche secondo Andy Jassy, CEO di Amazon,...
Audi mostra la sua prima auto di Formula...
Evolve3 85 e 75: Jabra presenta le prime...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 19:15.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v