Question

J'utilise le fragment de code suivant dans un script php pour mettre à jour en toute sécurité une ressource partagée.

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

Lorsque j'insiste sur le test de ce code avec un grand nombre de requêtes, un message d'erreur s'affiche:

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

Les sources php affichent le code suivant pour l'échec de l'acquisition de 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;
    }
}

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

Ma question est la suivante: puis-je ignorer cette erreur en toute sécurité et réessayer sem_acquire?

Modifier : j'ai mal compris ce problème, veuillez consulter la clarification que j'ai publiée ci-dessous.

raj

Était-ce utile?

La solution

Je ne voudrais pas ignorer ENOSPC (vous obtenez autre chose que EINTR, comme le montre le code). Vous risquez de 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 de traiter 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 en implémentation de PHP, mais j'essaierais d'éviter d'appeler sem_get () à chaque fois que vous souhaitez utiliser le sémaphore. Rangez la poignée à la place. Il se peut qu’une ressource soit associée à chaque appel de sem_get, et c’est là que vous manquez d’espace.

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

Autres conseils

Après avoir posté cette question, j'ai remarqué que j'avais mal interprété le code comme étant errno == EINTR et que je sautais dans conclusion. Donc, comme l'a souligné bog, l'erreur est ENOSPC et non EINTR . Après quelques recherches, j'ai trouvé la raison de ENOSPC . Le nombre de mémoires tampon annulées s'épuisait. J'ai augmenté le nombre de semmnu et maintenant le code fonctionne sans aucun problème. J'ai utilisé semmni * semms l comme valeur de semmnu

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top