Compartir la misma variable entre más de un programa independiente en Linux [closed]

5 minutos de lectura

avatar de usuario
Rifat Rousseau

Quiero compartir una variable entre más de un ejecutable C independiente en Linux. Es decir, un programa escribirá en una matriz y establecerá una bandera para que ningún otro programa pueda usarla, y después de esta operación desactivará la bandera y luego otro programa leerá la matriz. Intenté usar el mismo archivo de encabezado personalizado (que contiene la variable) en cada programa, pero parece que se crean diferentes instancias de las variables cuando se invocan los programas.

  • pista: IPC (Comunicación entre procesos), es un tema demasiado amplio para abordarlo en una respuesta aquí.

    – Nim

    21 de mayo de 2012 a las 11:41

  • Sí, es posible que desee echar un vistazo aquí. Dos ejecutables independientes se lanzan en diferentes procesos, por lo que deberá implementar algún tipo de comunicación entre ellos, utilizando enchufes, tuberíaetc… o incluso archivos.

    – Eitan T.

    21 de mayo de 2012 a las 11:47


  • Veo. Eso significa que se debe usar tubería en este caso. ¿Hay alguna forma más sencilla?

    –Rifat Rousseau

    21 de mayo de 2012 a las 11:48

  • @Rifat Pipes son bastante simples. Aquí está una buena explicación para introducirte a las pipas.

    – Eitan T.

    21 de mayo de 2012 a las 11:50


  • las tuberías son de hecho más simples que memoria compartida, Creo. Sin embargo, debe serializar su variable.

    – mooooooooooooooooooooooo

    21 de mayo de 2012 a las 11:57

avatar de usuario
moooeeeeep

Las variables que declare en sus encabezados generarán una copia cada vez que las incluya (a menos que las declare extern). Por supuesto, cuando se trata de procesos separados, cada proceso tendrá su propio espacio de memoria. Necesita utilizar técnicas más sofisticadas para eludir esto, es decir, comunicación entre procesos (IPC). Por ejemplo:

  • (nombrado) Tuberías
  • Enchufes
  • Memoria compartida

Tu pregunta se lee como memoria compartida es lo que desea, ya que por este medio múltiples procesos pueden acceder a las mismas regiones de memoria para compartir algunas variables. Tal vez eche un vistazo a esta pregunta y sus respuestas para ver un ejemplo.

Se requerirá que su programa cree algo de memoria compartida, por ejemplo, usando shmget y adjuntar el objeto de memoria compartida usando shmat. Cuando múltiples procesos acceden a las mismas regiones de memoria, siempre es un enfoque saludable agregar la sincronización de procesos durante la lectura/escritura en la variable, por ejemplo, usando un semáforo compartido (semget, semop).

Cuando haya terminado con su memoria compartida, debe desconectar (shmdt) de eso. Por lo tanto, le dice al núcleo que su proceso ya no necesita acceso a él. El proceso que creó el objeto de memoria/semáforo compartido también necesita destruirlos al final de su(s) programa(s). De lo contrario, residirá en la memoria, probablemente hasta que reinicie su máquina (ver shmctl, semctlespecialmente IPC_RMID).

Tenga en cuenta que para los objetos de memoria compartida “El segmento solo se destruirá después de que el último proceso lo separe”. Por lo tanto, desea asegurarse de que esto realmente suceda para todos sus procesos (shmdt).


En respuesta a los comentarios, aquí está el enfoque POSIX:

La memoria compartida System V (shmget(2), shmop(2), etc.) es una API de memoria compartida más antigua. La memoria compartida POSIX proporciona una interfaz más simple y mejor diseñada; por otro lado, la memoria compartida POSIX está algo menos disponible (especialmente en sistemas más antiguos) que la memoria compartida System V.

Ver también este resumen y aquí por ejemplo.

Finalmente, tenga en cuenta que

Los objetos de memoria compartida POSIX tienen persistencia del núcleo: existirá un objeto de memoria compartida hasta que el sistema se apague, o hasta que todos los procesos hayan desasignado el objeto y se haya eliminado con shm_unlink(3)


Para tener en cuenta la persistencia de los objetos de memoria compartida, no olvide agregar manejadores de señales a su aplicación que realizarán las operaciones de limpieza en caso de una terminación excepcional (SIGINT, SIGTERM, etc.).

  • no usar shmgetusa el posix shm_open en lugar de. esto es mucho menos doloroso de usar y no tiene el problema de las colisiones de teclas

    – Hasturkun

    21 de mayo de 2012 a las 12:35

  • @Hasturkun – ¡Gracias por el comentario! No los he usado hasta ahora, pero agregué una nota sobre esto para completar.

    – mooooooooooooooooooooooo

    21 de mayo de 2012 a las 12:54

  • @Hasturkun ¿Por qué? shmget tiene el problema de la colisión de llaves? ¿Podría explicarme eso con más detalle?、

    – Juan

    24 de enero a las 8:32

  • @John aquí puede encontrar alguna discusión sobre ese tema: stackoverflow.com/q/4175379/1025391

    – mooooooooooooooooooooooo

    25 de enero a las 8:08

avatar de usuario
jason

Considere el uso de la memoria compartida POSIX a través de shm_open y shm_unlink… Personalmente, creo que son más fáciles de usar y más directos que las antiguas llamadas IPC de System-V, como shmgetetc. ya que el identificador devuelto funciona exactamente como un descriptor de archivo que puede usar con llamadas como read, writeetc. De lo contrario, si desea acceder al objeto de memoria compartida representado por el descriptor de archivo a través de punteros normales, puede usar mmap en el descriptor de archivo devuelto por shm_open.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad