¿Qué determina si un ejecutable se puede ejecutar en diferentes procesos independientes simultáneamente?

¿Qué determina si un ejecutable se puede ejecutar en diferentes procesos independientes simultáneamente?

publiquéuna preguntasobre cómo ejecutar un ejecutable (un visor de PDF) en Wine de forma independiente en múltiples procesos (independiente significa que no hay comunicación entre ellos, no es computación paralela). Escuché que el editor de PDF (una edición mejorada del visor) de alguna empresa no puede hacer eso.

Preguntas

  • Entonces, me pregunto qué hace que un archivo ejecutable pueda o no ejecutarse de forma independiente en múltiples procesos.
  • ¿Está implementado por el propio programa, por algunas bibliotecas?
  • ¿No puede el sistema operativo hacer que eso suceda?

Respuesta1

Es casi seguro que esto lo implementa el propio programa, y ​​probablemente sea imposible que el sistema operativo lo fuerce para todos los programas excepto los más rudimentarios.

Sin embargo, si conoce la forma en que el programa decide que ya se está ejecutando, y esa manera es algo en lo que puede influir, entonces puede obtener un ejecutable para iniciar un nuevo proceso (o no).

Algunas aplicaciones lo hacen particularmente fácil, como Emacs. La forma estándar de ejecutar Emacs es iniciar un nuevo proceso para cada invocación. Pero también puede ejecutar Emacs explícitamente en modo servidor y luego ejecutarlo emacsclientexplícitamente para indicarle al servidor existente que visite un nuevo archivo.

Como ejemplo opuesto, Firefox ofrece una opción de línea de comandos -no-remoteque fuerza el inicio de un nuevo proceso, mientras que el valor predeterminado es interactuar con un proceso que ya se está ejecutando, si es posible.

Muchas aplicaciones sencillas y desarrolladas en casa comprobarán si ya se está ejecutando otra versión de sí mismas con solo realizar una consulta ps. Esto se puede evitar de diversas formas. El problema con el software industrial es que el usuario casi nunca sabe cómo una aplicación en particular decide si ya está en uso o no. Incluso en Unix, donde puedes inspeccionar todos los archivos abiertos con los que interactúa un ejecutable, no hay garantía de que puedas determinar cuál (si es que alguno de ellos) es responsable de registrar el hecho de que la aplicación se está ejecutando.

Respuesta2

Un proceso es una instancia de un programa. Un programa puede ser instanciado varias veces, es decir, se pueden crear varios procesos con el mismo código ejecutable cargado.Me gustaría citar una línea deEntendiendo el kernel de Linuxpor Daniel P. Bovet y Marco Cesati:

Es importante distinguir programas de procesos; varios procesos pueden ejecutar el mismo programaal mismo tiempo, mientras que un mismo proceso puede ejecutar varios programassecuencialmente.

Básicamente, esto significa que si bien un programa puede sercorreren varios casos, una sola instancia solo puede cargar un código ejecutable a la vez. Entonces, partiendo de ahí, podríamos decir quenadaevita que un programa se ejecute en múltiples instancias, porque no hay absolutamente ninguna razón para prohibirlo. Por supuesto, estos procesos no compartirán nada más que su código de ejecución. Las páginas de memoria, los descriptores de archivos (que pueden referirse a archivos idénticos), etc., son completamente independientes de un proceso a otro.

Otro punto me parece importante cuando se trata de sistemas tipo Unix (mismo libro):

Los sistemas operativos tipo Unix adoptanun modelo de proceso/núcleo.Cada proceso tiene la ilusión de que es el único proceso en la máquina., y tiene acceso exclusivo a los servicios del sistema operativo.

De hecho, esta es la razón por la que los sistemas Unix son multiprocesamiento/multiprogramación, o al menos, es la política en la que se basa esta característica. Entonces, debido a este mismo hecho, no hay manera de que un procesosaber de forma nativaque otro proceso, ejecutando exactamente el mismo código, está esperando o trabajando en otra CPU.

Sin embargo, cada proceso sabe una cosa: el sistema está siendo ejecutado por el kernel y los servicios del kernel están a disposición del proceso durante todo el tiempo que pasará trabajando en una CPU. Gracias a esto es posible que un procesoconsultael kernel sobre otros procesos que se ejecutan como instancias del mismo ejecutable. La primera solución que me viene a la mente es leer el /procsistema de archivos virtual. Este FS actúa como una interfaz entre el usuario/aplicación y el kernel (ya que estos archivos representan estructuras y datos del kernel). En este sistema de archivos, a cada proceso se le asigna un directorio (nombrado con su PID), y dentro de este directorio encontrará un enlace llamado exe. Por ejemplo, aquí está bashel directorio de mi proceso, PID 22343:

lrwxrwxrwx /proc/22343/exe -> /bin/bash*

Ahora, al explorar el sistema de archivos, podrá encontrar procesos que ejecutan el mismo código ejecutable, es decir, procesos para los cuales el exeenlace apunta al mismo archivo ejecutable.

Sin embargo, dado que no todos los sistemas Unix se implementan /procde la misma manera, los desarrolladores pretenden utilizar una solución más portátil, que se basa en algo que casi todos los sistemas Unix entienden: archivos normales. Para esto .pidsuelen estar aquí los archivos.

La mayoría de las veces, encontrará estos archivos en formato /run. Por ejemplo:

-rw-r--r-- /run/acpid.pid
-rw-r--r-- /run/atd.pid
-rw-r--r-- /run/crond.pid

Estos archivos son creados por la aplicación a la que pertenecen y se utilizan como marcadores de si se está ejecutando o no una instancia de un programa. Normalmente, el contenido de este archivo está compuesto simplemente por el PID del proceso en ejecución. En este caso, tengo un acpidproceso en ejecución, con PID 1503, y eso es exactamente lo que hay en el archivo PID.

Ahora bien, como todos los procesos de un mismo programa comparten el mismo código de ejecución, comparten sus constantes (al menos, sus valores). Por esta razón, si cada instancia sabe dónde buscar el archivo PID, programar un programa de instancia única es bastante sencillo:

if (the pid file exists) then
    send a signal to the running process or just bring it on the foreground
    exit since the work is going to be handled by the already-running process
else
    actually start the program, the first instance
endif

Usar señales en el primer caso es el comportamiento que más he visto, sin embargo, si tu aplicación usa algún IPC más sofisticado (sockets, colas de mensajes,...), podrías usarlo para informarle que el usuario ha solicitado algo que tiene que hacerlo.

información relacionada