2010-04-29 2 views
2

J'ai un script PHP dans les travaux qui est un travailleur de l'emploi; sa tâche principale est de vérifier une table de base de données pour de nouveaux emplois, et s'il y en a, d'agir sur eux. Mais les emplois vont venir dans en rafales, avec de longues lacunes entre les deux, donc je mis au point un cycle de sommeil comme:Quand un script démon PHP <5.3.0 reçoit-il des signaux?

while(true) { 
    if ($jobs = get_new_jobs()) { 
    // Act upon the jobs 
    } else { 
    // No new jobs now 
    sleep(30); 
    } 
} 

Bon, mais dans certains cas, cela signifie qu'il ya peut-être 30 secondes lag avant un nouvel emploi est agi sur. Comme il est un script démon, je me suis dit que je vais essayer le crochet pcntl_signal pour attraper un signal SIGUSR1 pour pousser le script de se réveiller, comme:

$_isAwake = true; 
function user_sig($signo) { 
    global $_isAwake; 
    daemon_log("Caught SIGUSR1"); 
    $_isAwake = true; 
} 
pcntl_signal(SIGUSR1, 'user_sig'); 

while(true) { 
    if ($jobs = get_new_jobs()) { 
    // Act upon the jobs 
    } else { 
    // No new jobs now 
    daemon_log("No new jobs, sleeping..."); 
    $_isAwake = false; 
    $ts = time(); 
    while(time() < $ts+30) { 
     sleep(1); 
     if ($_isAwake) break; // Did a signal happen while we were sleeping? If so, stop sleeping 
    } 
    $_isAwake = true; 
    } 
} 

je me suis cassé la sleep(30) en petits morceaux de sommeil, en cas un signal n'interrompt pas une commande sleep(), pensant que cela causerait au plus un délai d'une seconde, mais dans le fichier journal, je vois que le SIGUSR1 n'est pas détecté tant que les 30 secondes ne se sont pas écoulées (et peut-être les réinitialisations de boucle externes while).

J'ai trouvé la commande pcntl_signal_dispatch, mais seulement pour PHP 5.3 et supérieur. Si j'utilisais cette version, je pourrais passer un appel à cette commande avant l'appel if ($_isAwake), mais tel qu'il est actuellement, je suis sur 5.2.13.

Dans quelles situations la queue de signaux est-elle interprétée dans les versions de PHP sans avoir le moyen d'appeler explicitement l'analyse de la file? Pourrais-je mettre une autre commande inutile dans cette boucle de sommeil qui déclencherait une analyse de file d'attente de signal à l'intérieur?

Répondre

2

Correction de mon propre problème: La réponse est la déclaration "ticks". J'avais, dans le cadre du démarrage du processus Daemon fait l'action declare(ticks=1);, mais il ne semblait pas se reporter au script principal (puisque c'était dans une fonction, dans un fichier include?) Ajout d'une ligne declare(ticks=1) avant la boucle while(true) provoque la transmission immédiate des signaux (c.-à-d. que la commande sleep(1) provoque une coche, donc, après le réveil, les signaux sont traités)

Questions connexes