Newsgroup: it.comp.os.linux.sys
Titolo: ipcs sotto pressione [lungo]

Ciao a tutti,
Ho un problemino rognoso rognoso. Parliamo di semafori ipcs, server 
linux (debian lenny), php5.
Ho implementato un webservice che interagisce con svariati client 
scritti in VB mediante SOAP. C'é un operazione che deve avere 
granularitá atomica, cioé se due client cercano di farla in 
contemporanea devo aspettare che il primo finisca prima di far inizare 
il secondo.
Ho risolto in modo molto elegante con i semafori IPCS. In sostanza 
all'inizio della funzione incriminata c'é questo codice:
// file del semaforo
$semFile = dirname(__FILE__).'/../include/config.inc.php';
// key semaforo
$SEMKEY = ftok($semFile,'S');
// Creo il semaforo
$sem_id = sem_get($SEMKEY, 1);
if ($sem_id !== false) {
	logga(__METHOD__." Semaforo creato",NORMAL_LOG);
	// Acquisisco il semaforo - resto in attesa finchè non è libero
	if (sem_acquire($sem_id)) {
		logga(__METHOD__." Semaforo acquisito",NORMAL_LOG);
	} else {
		logga(__METHOD__." Errore 1",NORMAL_LOG);
		sem_remove($sem_id);
	}
}
Poi eseguo tutto quanto quello che deve accadere, e termino la funzione con
/***** rilascio il semaforo *****/
if (sem_release($sem_id)){
	logga(__METHOD__." Semaforo rilasciato",NORMAL_LOG);
} else {
	logga(__METHOD__." Errore 2",NORMAL_LOG);
	sem_remove($sem_id);
}
/***** end rilascio il semaforo *****/
Nell'ambiente di staging, nel quale ho circa il 10% del traffico, 
funziona tutto alla grande, e si comporta come dovrebbe, ma soprattutto 
va avanti da almeno un anno senza fare una piega.
Appena ho passato la funzione nell'ambiente di produzione mi sono andati 
in palla i semafori, ed il log si fermava alla creazione del semaforo, 
fino a che non andava in timeout lo script:
Dec 13 12:10:51 dns2 EDIWEB-> [28696]: [2010/12/13 
12:10:51]Srv::confermaEvasione Semaforo creato
[Mon Dec 13 12:12:03 2010] [error] [client 1.2.3.4] Premature end of 
script headers: server_visuristi.php
Verificando con il comando ipcs c'erano soltanto 4 semafori appesi a 
nome dell'user del webservice (consorzio):
dns2:~# ipcs
------ Shared Memory Segments --------
key        shmid    owner    perms    bytes      nattch     status
0x01000057 0        root     600      512000     2
0xf90065f0 32769    root     600      189        1
------ Semaphore Arrays --------
key        semid      owner      perms      nsems
0x00000000 65536      hpsmh     600        1
0x00000000 98305      hpsmh     600        1
0x00000000 131074     hpsmh     600        1
0x00000000 251068419  www-data  600        1
0x00000000 251101188  www-data  600        1
0x00000000 251133957  www-data  600        1
0x00000000 251166726  www-data  600        1
0x00000000 251199495  www-data  600        1
0x00000000 251232264  www-data  600        1
0x00000000 251265033  www-data  600        1
0x00000000 251297802  www-data  600        1
0x00000000 251330571  www-data  600        1
0x00000000 251363340  www-data  600        1
0x5305f99b 524301     consorzio 666        3
0x5305634c 49709070   consorzio 666        3
0x53057ac1 94633999   consorzio 666        3
0x5305f6e5 248741904  consorzio 666        3
------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages
0x230065be 0          root       600        0            0
0x000004d2 65537      root       666        0            0
Killando il primo si é sbloccata la situazione, nel senso che tutti i 
processi in attesa sono usciti con un errore relativo al semaforo 
inesistente.
Ora in produzione ho tolto i semafori, anche perché la sovrapposizione é 
un eventualitá rarissima, ma vorrei capire come mai sono andati in 
palla.. Qualche idea?
-- 
g4b0, linux user n. 369000
http://brosulo.net

 palla.. Qualche idea?
Se un client muore (o non riesce a comunicare) in qualsiasi momento 
durante la transazione c'e' un timeout che termina tutto e rilascia il 
semaforo ?
Giulia

 all'inizio della funzione incriminata c' questo codice:
Queste sono le situazioni che mi fanno apprezzare ancora di più
Twisted :-)


In teoria quando lo script php termina l'esecuzione i semafori ad esso 
associati vengono rilasciati. Inoltre il client non centra nulla, in 
quanto fa solo la chiamata alla funzione e rimane in attesa della 
risposta, se si schianta la funzione php dovrebbe comunque arrivare al 
termine dell'esecuzione, rilasciando quindi il semaforo. O no?


 Twisted :-)
Perché? Non sono afferratissimo di Twisted...


 termine dell'esecuzione, rilasciando quindi il semaforo. O no?
No.
Se crasha prima della fine, ipotesi tutt'altro che trascurabile, il 
semaforo non viene rilasciato.
Switcha a metodi più tradizionali utilizzando i locks su file.
Se muore il processo che detiene il lock lo stesso viene rilasciato.

 Perch ? Non sono afferratissimo di Twisted...
Twisted è un framework in Python che ti permette di lavorare in
maniera asincrona.
Detta in parole povere, hai un unico thread (il reactor) che si occupa
di gestire l'applicazione e di sollevare i vari eventi.
In questo modo ti toglie tantissimi problemi legati alla concorrenza
(ad es. semafori).
Dagli un'occhiata perchè merita. Non è intuitivo, ma una volta capito
è potentissimo

 č potentissimo
Lo faró, grazie mille!


 Se muore il processo che detiene il lock lo stesso viene rilasciato.
Verifico subito di che si tratta, pensavo fosse un metodo vetusto, ma 
forse mi sbaglio :)


 forse mi sbaglio :)
Anche UNIX è vetusto.
Però funziona ancora nonostante sia degli anni '70


Beh, windows server 2010 é meglio, no? :P
A parte gli scherzi, ai bei tempi dell'universitá l'esame di sistemi 
operativi si é incentrato sulla shared memory ed i semafori, dando 
un'occhiata veloce al file di lock, per cui ho dato per scontata questa via.
