threads semaphores sem_wait sem_init operating example c linux ipc posix semaphore

semaphores - ¿Cómo evito que sem_open() falle con ENOSYS?



semaphore.h example (5)

Tengo dos sistemas Slackware Linux en los que el semáforo POSIX sem_open() falla con errno establecido en 38. Código de ejemplo para reproducir a continuación (el código funciona bien en CentOS / RedHat).

¿Hay alguna opción de configuración del kernel o del sistema que pueda causar esto? ¿Otras sugerencias?

Los sistemas con problemas son Slackware 10.1.0 kernel 2.6.11 /lib/librt-2.3.4.so /lib/libpthread-0.10.so, pero el mismo código funciona en el núcleo mucho más antiguo de RedHat 9 2.4.20 / lib / librt -2.3.2.so /lib/tls/libpthread-0.29.so. (y también funciona en CentOS 5 kernel 2.6.18 /lib/librt-2.5.so /lib/i686/nosegneg/libpthread-2.5.so).

man sem_open sugiere que errno significa que sem_open() no es compatible con el sistema.

#define ENOSYS 38 /* Function not implemented */

El espacio de usuario sem_open() está en librt que librt forma dinámica y librt está presente en los sistemas afectados.

El sistema afectado afirma que admite semáforos POSIX: _POSIX_SEMAPHORES es verdadero y sysconf(_SC_SEMAPHORES) confirma.

Gracias, Kieran

Editar 1: He agregado más detalles sobre las versiones de software en uso y eliminé algunos comentarios irrelevantes.

Edición 2: / dev / shm está montado en los buenos sistemas y no está montado en los sistemas defectuosos. Montarlo no cambió el comportamiento en los sistemas afectados. Creo que / dev / shm también es necesario, pero sem_open () está fallando antes de eso, y strace lo admite.

# /* Quick''n''dirty test program to illustrate sem_open failure #Run this file to auto-build test and run as a.out # Build gcc $0 -lrt if [ $? -ne 0 ] ; then exit ; fi # Run $( dirname $0)/a.out exit */ #include <stdio.h> #include <fcntl.h> #include <errno.h> #include <unistd.h> #include <semaphore.h> int main(int argc, char *argv[]) { const char *SEM_NAME = "SHRMEM_SCXL"; /* name of mutex */ sem_t *mutex = SEM_FAILED; /* ptr to mutex */ #ifdef _POSIX_SEMAPHORES printf("_POSIX_SEMAPHORES %ld/n", _POSIX_SEMAPHORES); #else puts("Undefined"); #endif printf("sysconf %s/n", sysconf(_SC_SEMAPHORES) ? "Yes" : "No" ); mutex = sem_open(SEM_NAME, O_CREAT, 0666, 1); if (mutex == SEM_FAILED) printf("Failed %d/n", errno); else { puts("Success - pause while you check /dev/shm "); sleep(5); sem_close(mutex); sem_unlink(SEM_NAME); } }


¿Está / dev / shm montado? Es posible que las versiones anteriores de slackware no hayan montado este sistema de archivos al arrancar. Desde / etc / fstab:

tmpfs /dev/shm tmpfs defaults 0 0

Editar: Probablemente ese no sea el problema después de todo. Creo que puede que necesites actualizar tu kernel o incluso librt.

Edit2: Creo que para slackware 11, que creo que está utilizando, necesitará un núcleo más nuevo que 2.6.13 para usar las bibliotecas de subprocesamiento NPTL (libs en / lib / tls) que parecen ser necesarias para el sem_open para trabajo.

Edit3: Logré hacer que funcione con un cuadro de slackware 11 que tengo a) montando / dev / shm yb) estableciendo la variable de entorno LD_ASSUME_KERNEL a 2.6.13 (cualquier versión del kernel> 2.6.12 funcionará). Eso parece funcionar a pesar de que el kernel es 2.6.11.11, pero otras cosas, como los hilos, podrían no funcionar.


Estaba trabajando con las colas de mensajes posix. Tengo el mismo error. Error de mq_open con errono 38 (ENOSYS).

El trabajo alrededor es reconstruir el kenel con POSIX MESSGE QUEUE habilitado en la configuración del kernel.

Esto construirá el kernel con soporte de cola de mensajes POSIX y funcionó para mí.

Gracias


La hipótesis del "proceso compartido no funciona" no tiene sentido para mí. No es que lo ayude, pero si tiene tiempo e inclinación, puede intentar lo siguiente para ver si el aspecto "proceso compartido" es lo que está fallando:

  1. crea un semáforo usando sem_init en la memoria no compartida (para hilos). Si funciona, entonces los sema4s funcionan dentro del proceso.

  2. repetir experimento en memoria compartida. Esto debería decirle si funcionan entre procesos. Tenga en cuenta que puede que necesite intentar usar el sema4 para ver si funciona entre procesos.


Las versiones anteriores de las bibliotecas de subprocesos no admiten compartir semáforos POSIX entre procesos. Del man sem_init

El argumento pshared indica si el semáforo es local al proceso actual (pshared es cero) o si se va a compartir entre varios procesos (pshared no es cero). LinuxThreads actualmente no admite semáforos compartidos por proceso, por lo que sem_init siempre devuelve con el error ENOSYS si pshared no es cero.

Como sem_open () crea semáforos con nombre, siempre intenta compartirlos entre procesos.

Para admitir el intercambio de semáforos anónimos entre los procesos con sem_init () en Slackware 10

  • actualizar libpthread y (posiblemente) librt
  • actualizar el kernel

Además, para admitir el uso compartido de semáforos con sem_open ()

  • agregue una línea a /etc/fstab para montar /dev/shm como un tmpfs

    tmpfs / dev / shm tmpfs valores predeterminados 0 0

  • ejecutar mount /dev/shm o reiniciar