Error EINTR para llamada de semop
Pregunta
Estoy usando el siguiente fragmento de código en un script php para actualizar de forma segura un recurso compartido.
$lock_id = sem_get( ftok( 'tmp/this.lock', 'r'));
sem_acquire($lock_id)
//do something
sem_release($lock_id)
Cuando hago una prueba de esfuerzo de este código con una gran cantidad de solicitudes, aparece un error:
Warning: semop() failed acquiring SYSVSEM_SETVAL for key 0x1e: No space left on device in blahblah.php on line 1293
las fuentes php muestran el siguiente código para la adquisición fallida 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;
}
}
lo que significa que semop falla con EINTR. La página man revela que la llamada al sistema semop () fue interrumpida por una señal.
Mi pregunta es: ¿puedo ignorar este error y volver a intentar sem_acquire?
Editar : he entendido mal este problema, por favor vea la aclaración que he publicado a continuación.
raj
Solución
No ignoraría el ENOSPC (está obteniendo algo más que EINTR, como muestra el código). Puede terminar en un bucle ocupado esperando un recurso que haya agotado anteriormente. Si no tiene espacio en algún lugar, debe asegurarse de abordar ese problema. ENOSPC generalmente significa que te has quedado sin ... algo.
Un par de ideas aleatorias:
No soy un experto en la implementación de PHP, pero trataría de evitar llamar a sem_get ()
cada vez que desee el semáforo. Guarde la manija en su lugar. Puede ser que algún recurso esté asociado con cada llamada a sem_get, y ahí es donde se está quedando sin espacio.
Me aseguraría de comprobar que el error vuelve en sem_get ()
. Es un fragmento de código, pero si no pudiera obtener el sema4, obtendría resultados inconsistentes al intentar sem_op ()
(tal vez EINTR tenga sentido)
Otros consejos
Después de publicar esta pregunta, noté que leí mal el código como errno
==
EINTR
y salté a conclusión. Entonces, como ha señalado el pantano, el error es ENOSPC
y no EINTR
. Después de investigar un poco, encontré el motivo de ENOSPC
. El número de amortiguadores de deshacer se estaba agotando. He aumentado el número de semmnu
y ahora el código se está ejecutando sin problemas. He usado semmni * semms
l como el valor de semmnu