2008-11-07 9 views
1

J'utilise le fragment de code suivant dans un script PHP pour mettre à jour en toute sécurité une ressource partagée.Erreur EINTR pour l'appel semop

$lock_id = sem_get(ftok('tmp/this.lock', 'r')); 
sem_acquire($lock_id) 
//do something 
sem_release($lock_id) 

Quand je test de stress ce code avec un grand nombre de demandes que j'obtiens une erreur:

Warning: semop() failed acquiring SYSVSEM_SETVAL for key 0x1e: No space left on device in blahblah.php on line 1293 

sources php montrent le code suivant pour échec l'acquisition SYSVSEM_SETVAL

while (semop(semid, sop, 3) == -1) { 
    if (errno != EINTR) { 
     php3_error(E_WARNING, "semop() failed acquiring SYSVSEM_SETVAL for key 0x%x: %s", key, strerror(errno)); 
     break; 
    } 
} 

qui signifie semop échoue avec EINTR. man page révèle que l'appel système semop() a été interrompu par un signal.

Ma question est de savoir si je peux ignorer cette erreur et réessayer sem_acquire?

Modifier: J'ai mal compris ce problème, Pl voir la clarification que j'ai posté ci-dessous.

raj

Répondre

1

Je ne l'ignorer ENOSPC (vous obtenez autre chose que EINTR, comme le code montre). Vous pouvez vous retrouver dans une boucle occupée en attendant une ressource que vous avez épuisée auparavant. Si vous manquez d'espace quelque part, vous voulez vous assurer que vous faites face à ce problème. ENOSPC signifie généralement que vous êtes hors de ... quelque chose.

Quelques idées au hasard:

Je ne suis pas un expert sur la mise en œuvre de PHP, mais je vais essayer d'éviter d'appeler sem_get() chaque fois que vous voulez que le sémaphores. Stockez la poignée à la place. Il se peut que certaines ressources soient associées à chaque appel à sem_get, et c'est là que vous manquez d'espace.

Je m'assurerais de vérifier vos retours d'erreur sur sem_get(). Il est un extrait de code, mais si vous deviez ne parviennent pas à obtenir le sema4, vous obtiendrez des résultats incohérents en essayant de sem_op() il (peut-être EINTR est logique)

0

Après avoir affiché cette question, je remarque que j'ai mal lu le code comme errno==EINTR et a sauté dans la conclusion. Donc, comme bog a souligné, l'erreur est ENOSPC et non EINTR. Après quelques recherches, j'ai trouvé la raison de ENOSPC. Le nombre de tampons d'annulation s'épuisait. J'ai augmenté le nombre de semmnu et maintenant le code fonctionne sans problèmes. J'ai utilisé semmni*semms l comme valeur de semmnu