Newsgroup: it.comp.www.php
Titolo: Sincronizzare funzione

Come posso fare in modo che una funzione non sia eseguita
contemporaneamente?
Ho provato a creare un file:
    // utilizzo un file per il lock
    $lockfile = "modules/NewsGroups/lck/fetch_articles.tmp";
    if ($f = @fopen($lockfile, "wb") == false)
        {
        die("Impossibile ottenere il lock");
        return;
        }
sorprendentemente, anche se il file e' ancora aperto, l'altro processo
riesce a crearlo comunque (mi sembra un comportamento anomalo) e non
entro mai nel die()
Cosa sbaglio?
C'e' qualche altro modo per ottenere di non far eseguire piu' volte la
stessa funzione?

 stessa funzione?
Dipende, che cosa dovrebbe fare tale funzione?
-- 
I am what I am, I do what I can
Sei un newbie? Leggi questo 
http://url.repository.biz/go/3C
Vuoi supportarmi? 
http://url.repository.biz/go/3E
Do. Or do not. There is not try.

Ho riscritto la funzione con l'flock ma non funziona comunque...
Dovrebbe essere lanciata una volta sola, quando e' terminata puo'
essere rilanciata da un altro processo ma se e' in esecuzione il
secondo processo deve saltarla
questo e' il link:
http://www.3bsoft.com/newsgroups_list.html
(c'e' gia' un processo in esecuzione che sta scaricando i messaggi,
dovrebbe andare sul die() ed invece anche il secondo processo prova a
scaricare di nuovo gli stessi messaggi)
e questa e' la funzione che ho appena riscritto:
function fetch_articles($cron){
    global $t, $myng, $db;
    // utilizzo un file per il lock
    $lockfile = "modules/NewsGroups/lck/fetch_articles.tmp";
	$fp = fopen($lockfile, "w+");
	if (flock($fp, LOCK_EX)) { // Esegue un lock esclusivo
	   //fwrite($fp, "Write something here\n");
	   //flock($fp, LOCK_UN); // rilascia il lock
	} else {
	   die("Non si riesce ad eseguire il lock del file !");
	   fclose($fp);
	   return;
	}
    // Get the required Info
	// Cerca nei newsgroup dopo 15 minuti dall'altimo tentativo andato a
vuoto
	$consulta = "SELECT * FROM myng_newsgroup,myng_server "
		."WHERE grp_serv_id = serv_id and last_download<".time()."-60*15
order by last_download limit 0, 1";
	$result = $db->sql_query($consulta);
	while ($Record = $db->sql_fetchrow($result)) {
		// Fetch the server's data
		$server = $Record['serv_host'];
		$port = $Record['serv_port'];
		$login = $Record['serv_login'];
		$passwd = $Record['serv_passwd'];
        $grp_id = $Record['grp_id'];
		// Fetch Articles for the group
		$ns = OpenNNTPconnection($server,$port,$login,$passwd);
		if ($ns == true) {
			// Connection Completed!
	   		// Get new articles.
	        $new_articles =
check_new_articles($ns,$Record['grp_name'],$Record['grp_last_article'],$Record['grp_num_messages']);
			closeNNTPconnection($ns);
			flush();
	        // aggiorno la data dell'ultimo download in MYNG_NEWSGROUP
	        //  (solo se ho fatto il download di tutti i messaggi
disponibili)
	        if ($new_articles==0) {
				$consulta = "update myng_newsgroup set last_download=".time()
				   ." WHERE grp_id =".$grp_id;
			    $db->sql_query($consulta);
			}
		}
	}
	flock($fp, LOCK_UN); // rilascia il lock
	fclose($fp);
	//unlink($lockfile);
 
}

 Ho riscritto la funzione con l'flock ma non funziona comunque...
L'hai riscritta male ...
<?php
$fp = fopen("lock.txt", "w+");
if ($fp !== false) {
	while (!flock($fp, LOCK_EX)) { 
		// attendi fin tanto che non hai acquisito il lock
		// inserire qui un qualche tipo di gestore
		// del timeout
	}
	print ('<pre>' . date("l dS of F Y h:i:s A") . "\r\n");
	sleep(5); // finta attesa, inserire qui il codice da eseguire
	print (date("l dS of F Y h:i:s A") . '</pre>');
	flock($fp, LOCK_UN);
	fclose($fp);
} else {
	echo "Couldn't open the file !";
}
?>
Apri lo script in due finestre diverse "contemporaneamente" ed otterrai
un risultato come quello che segue:
- nella prima finestra aperta:
Tuesday 13th of September 2005 08:46:10 PM
Tuesday 13th of September 2005 08:46:15 PM
- nella seconda finestra aperta:
Tuesday 13th of September 2005 08:46:15 PM
Tuesday 13th of September 2005 08:46:20 PM
Ossia il codice nella seconda finestra e' stato eseguito solo dopo
quello nella prima


 L'hai riscritta male ...
l'errore era qui:
 if (flock($fp, LOCK_EX + LOCK_NB)) { // Esegue un lock esclusivo
(senza LOCK_NB l'altro processo andava in attesa...)