[Linux] Comunicación entre procesos: semáforo System V

Tabla de contenido

palabras escritas delante

comprensión de algunos conceptos

La introducción de los semáforos

El concepto y uso de semáforos


 

palabras escritas delante

        Los semáforos System V son un mecanismo IPC de nivel inferior que requiere manipulación manual y sincronización cuando se usa. En los sistemas operativos modernos, los semáforos POSIX ( sem_*operados a través de una serie de funciones) o las primitivas de sincronización más avanzadas (como mutexes, variables de condición, etc.) se usan más comúnmente para lograr la comunicación y sincronización entre procesos. Así que aquí solo hablaré sobre el proceso general de uso, pero lo explicaré en detalle. Lo explicaremos en detalle más adelante en semáforos POSIX.

comprensión de algunos conceptos

        Nuestro último artículo habló sobre la memoria compartida de System V, podemos saber:

Para permitir la comunicación entre procesos ---> es necesario permitir que diferentes procesos vean el mismo recurso ---> incluidos todos los métodos de comunicación anteriores, es prioritario resolver un problema: permitir que diferentes procesos vean el mismo recurso.

        Sin embargo, permitir que diferentes procesos vean el mismo recurso, como la memoria compartida, traerá algunos problemas de tiempo . Por ejemplo, el escritor solo escribe la mitad y el lector solo lo lee. Es decir, la falta de control de acceso causará inconsistencia de datos . .

        El sistema operativo interno de la tubería ya los ha manejado, por lo que no hay necesidad de preocuparse por estos problemas de tiempo.

        Aquí nosotros

        1. Un recurso común visto por múltiples procesos (flujo de ejecución) se denomina recurso crítico

        2. Llame a su propio proceso y al código que accede a los recursos críticos una sección crítica .

Por ejemplo el ejemplo del capítulo anterior:

         Todo el código solo tiene estas dos líneas para acceder al recurso crítico shmaddr, por lo que se llama sección crítica.


Cuando se utiliza la memoria compartida, varios flujos de ejecución interfieren entre sí durante la ejecución. El principal motivo es que accedimos al mismo recurso (recurso crítico) sin protección . En una sección no crítica, múltiples secuencias de ejecución no se afectan entre sí.

        3. Para proteger mejor el área crítica, solo un proceso puede ingresar y acceder al área crítica en cualquier momento en el flujo de ejecución múltiple , lo que se denomina exclusión mutua . Esta exclusión mutua se explicará en detalle más adelante en subprocesos múltiples.


La introducción de los semáforos

        Permítanme dar un ejemplo primero: cuando vamos al cine, debemos tener un asiento (un recurso en la sala de proyección) ¿Este asiento le pertenece solo si se sienta en él? Obviamente no, primero tengo que comprar un boleto, siempre que compre un boleto, tengo este asiento, no importa si estoy allí o no, ese asiento me pertenece.

        Entonces la esencia de la compra de boletos: el mecanismo de |reserva| de asientos .         

        En consecuencia, cada proceso quiere ingresar a un recurso crítico y acceder a una parte del recurso crítico. No se puede permitir que el proceso use el recurso crítico directamente (el usuario no puede ir directamente a la sala de cine para tomar un asiento), sino solicitar un semáforo primero (primero en llegar a comprar un billete).

        La esencia del semáforo es un contador , similar a int count = n (un ejemplo menos preciso, por ahora, entiéndelo así).

        Así que solicita el semáforo:

        1. La esencia de solicitar un semáforo es: dejar que el semáforo contrarreste...

        2. Siempre que la solicitud del semáforo sea exitosa, los recursos que desea deben reservarse dentro del recurso crítico --- la solicitud del semáforo es en realidad un mecanismo de reserva para el recurso crítico.

       3. De manera similar, el uso de recursos críticos necesita liberar el semáforo, que es esencialmente semáforo++.

        Suponiendo que hay 10 recursos pequeños en un recurso crítico y hay 11 procesos en este momento, los primeros 10 procesos acceden al recurso crítico y solicitan un semáforo con éxito. El último proceso solo puede bloquearse porque los recursos en el recurso crítico están siendo utilizados Espere a que se agoten los recursos del proceso interno.


        Lo anterior ha estado hablando de semáforos, entonces, ¿ qué es exactamente un semáforo ?

        Se mencionó anteriormente que el semáforo es un contador , entonces, ¿qué es este contador?

        En primer lugar, el contador no debe ser una variable local , por lo que no se puede asociar el contador a cada proceso, porque cada proceso tiene su propio contador, lo cual es un absurdo.

        Si es una variable global, cuando los procesos padre e hijo soliciten el semáforo, se producirá una copia en escritura, lo que hará que los procesos padre e hijo tengan cada uno una copia de la variable, lo que no es bueno.

        Luego suponga que varios procesos pueden ver el mismo n (es decir, n está en la memoria compartida), y luego todos pueden solicitar el semáforo en este momento.

La respuesta también es no .

        En primer lugar, necesitamos saber que el cálculo se realiza en la CPU y los datos n se almacenan en la memoria.

Cuando la CPU ejecuta una instrucción, debe realizar los siguientes tres pasos:

        1. Cargue los datos en la memoria al registro de la CPU

        2.n--(analizar && ejecutar instrucciones)

        3. Vuelva a escribir el n modificado de la cpu en la memoria.

        Esto parece estar bien, pero el flujo de ejecución puede cambiarse en cualquier momento durante la ejecución.

        Cuando se cambia, quitará sus propios datos de contexto (incluido n), y luego, cuando se vuelve a cambiar, escribirá sus propios datos de contexto en el registro de la CPU y continuará ejecutándose.

Entonces hay un problema:

        Supongamos que hay 10 procesos, respectivamente 1, 2, 3, 4..., 9, 10, y solo hay 5 recursos críticos, por lo que el semáforo n también es 5.

        Suponga que 1 solicita un semáforo primero, pero tiene la mala suerte de ejecutar el primer paso y se corta. Luego, 2, 3, 4, 5 y 6 solicitan un semáforo normalmente. En este momento, el semáforo ya es 0, y los 7 siguientes ya no podrá solicitar el trámite hasta el 10.

        Pero en este momento, el número 1 continúa ejecutándose nuevamente. Dado que n es 5 cuando entra por primera vez, continúe ejecutando los pasos 2 y 3, n-- es 4, y luego escríbalo de nuevo en la memoria. esta vez, n cambia de 0 a 4, ¿no es esto malo? Obviamente no hay recursos, pero el semáforo se convierte en 4, y el proceso posterior puede seguir aplicándose, por lo que debe ser incorrecto.       

        Así que n, debido a problemas de temporización, n tiene un estado intermedio, lo que puede causar inconsistencia en los datos, pero si n tiene solo una línea de ensamblaje, ¡entonces la operación es atómica !

Entonces 4. Atomicidad: O no lo haces, o lo haces, no hay un estado intermedio, se llama atomicidad .


El concepto y uso de semáforos

concepto:

Un semáforo System V es un mecanismo de comunicación entre procesos (IPC) proporcionado en el sistema operativo para implementar la sincronización y la exclusión mutua entre procesos. Controla el acceso a los recursos operando sobre contadores.

Los semáforos del Sistema V se identifican mediante un identificador entero (identificador de semáforo) y cada identificador corresponde a un conjunto de semáforos (conjunto de semáforos). Un conjunto de semáforos puede contener varios semáforos individuales, cada uno con un valor entero no negativo.

usar:

Los semáforos System V proporcionan las siguientes tres operaciones básicas:

  1. Crear conjunto de semáforos: semget()cree un nuevo conjunto de semáforos mediante una llamada al sistema. Esta llamada devuelve un identificador de semáforo para operaciones de semáforo posteriores.

  2. Control de colecciones de semáforos: use semctl()llamadas al sistema para controlar las colecciones de semáforos. A través de esta llamada, puede establecer el valor inicial del semáforo, obtener o cambiar el valor del semáforo, eliminar el conjunto de semáforos, etc.

  3. Manipulación de semáforos: use semop()llamadas al sistema para manipular semáforos. La llamada acepta un identificador de semáforo y un conjunto de operaciones que se pueden utilizar para adquirir o liberar el semáforo y realizar otras operaciones de control.

semop()Las operaciones aceptadas por la llamada al sistema incluyen:

  • Operación P (espera): Decrementando el valor del semáforo en uno (si el valor del semáforo es mayor que cero), o haciendo que el proceso de llamada entre en estado de espera (si el valor del semáforo es cero).
  • Operación V (liberación): agregando uno al valor del semáforo y despertando otros procesos que esperan el semáforo.
  • A través de una combinación y operación adecuadas, se puede realizar el acceso mutuamente excluyente a los recursos y el control de concurrencia. Múltiples procesos pueden coordinar sus acciones a través de la operación del semáforo para garantizar la consistencia y corrección de los datos.

Cuando se presentan funciones relacionadas con semáforos de System V, las funciones comúnmente utilizadas incluyen semget(), semctl()y semop(). Lo siguiente introducirá sus parámetros y uso:

  1. semget()función:

    int semget(key_t key, int nsems, int semflg);
    
    • parámetro:
      • key: Valor de clave única, utilizada para identificar el conjunto de semáforos a crear o adquirir.
      • nsems: especifica el número de semáforos en el conjunto de semáforos.
      • semflg: Parámetro de bandera, utilizado para especificar el método de creación y los derechos de acceso del semáforo.
    • uso:
      • Al especificar un valor clave y otros parámetros, la semget()función de llamada puede crear un nuevo conjunto de semáforos u obtener un conjunto de semáforos existente.
      • El valor devuelto es un identificador de semáforo, que se utiliza para el control y funcionamiento posterior del conjunto de semáforos.
  2. semctl()función:

    int semctl(int semid, int semnum, int cmd, ...);
    
    • parámetro:
      • semid: El identificador del semáforo, utilizado para especificar el conjunto de semáforos que se operará.
      • semnum: Especifique el índice del semáforo específico en la colección, que se utiliza para identificar el semáforo que se operará.
      • cmd: El comando de control a ejecutar, usado para especificar una operación específica.
      • arg: Parámetros que deben proporcionarse de acuerdo con diferentes comandos.
    • uso:
      • semctl()Las funciones se utilizan para controlar y administrar colecciones de semáforos.
      • Se pueden lograr diferentes operaciones especificando diferentes comandos de control ( cmd), como establecer el valor inicial del semáforo, obtener o cambiar el valor del semáforo y eliminar el conjunto de semáforos.
      • Los parámetros exactos (por ejemplo, arg) varían de un comando a otro.
  3. semop()función:

    int semop(int semid, struct sembuf *sops, unsigned nsops);
    
    • parámetro:
      • semid: El identificador del semáforo, utilizado para especificar el conjunto de semáforos que se operará.
      • sops: sembufUn puntero a una matriz de estructura, que contiene un conjunto de operaciones.
      • nsops: Especifica el número de operaciones.
    • uso:
      • semop()Las funciones se utilizan para operar en semáforos.
      • Al combinar diferentes operaciones, se pueden realizar operaciones como la adquisición y liberación de semáforos.
      • sopsEl parámetro es un sembufpuntero a una matriz de estructura, y sembufla estructura define la información específica de cada operación, incluido el número del semáforo, el tipo de operación (operación P o operación V) y el indicador de operación.
      • nsopsEl parámetro especifica el número de operaciones a realizar.

en. La estructura sembuf es más o menos como sigue:

 

sembufUna estructura es una estructura utilizada para especificar operaciones en un semáforo de System V y contiene los siguientes campos:

  1. unsigned short sem_num: Especifica el índice del semáforo a operar en la colección, contando desde 0.
  2. short sem_op: Especifica la acción a realizar.
    • Si sem_opel valor es mayor a 0, significa que se realiza la operación V (liberar), es decir, se incrementa el valor del semáforo.
    • Si sem_opel valor es menor que 0, significa realizar la operación P (esperar), es decir, reducir el valor del semáforo.
    • Si sem_opel valor del semáforo es igual a 0, significa que se realiza la operación Z (cero), y si el valor del semáforo es 0, espera. Esta operación se usa típicamente en operaciones síncronas para esperar a que ocurra una determinada condición.
  3. short sem_flg: Indicadores utilizados para especificar una acción.
    • IPC_NOWAIT: Si no se puede realizar la operación (por ejemplo, el valor del semáforo es 0 y sem_opnegativo), volver inmediatamente sin esperar.
    • SEM_UNDO: Cuando el proceso finaliza inesperadamente, el sistema cancelará automáticamente la operación del proceso en el semáforo para evitar un punto muerto.

Supongo que te gusta

Origin blog.csdn.net/weixin_47257473/article/details/132136874
Recomendado
Clasificación