¿Qué es un semáforo? ¿De qué partes se compone? ¿Qué significa el valor del semáforo?
Describir
Editar
Tome como ejemplo el funcionamiento de un estacionamiento. Para simplificar, supongamos que solo hay tres espacios de estacionamiento en el estacionamiento y que los tres espacios de estacionamiento están vacíos al principio. Si llegan cinco coches al mismo tiempo, el guardia dejará entrar a tres de ellos y bajará el tren. El resto de coches deberán esperar en la entrada, y los coches que lleguen más tarde deberán esperar en la entrada. En ese momento, un automóvil salió del estacionamiento. Cuando el guardia se enteró, abrió el estacionamiento y colocó uno afuera. Si deja dos coches atrás, puede meter dos más, y así sucesivamente.
En este sistema de aparcamiento, las plazas de aparcamiento son recursos públicos, cada coche es como una fila y el portero actúa como un semáforo.
Categoría
Editar
Semáforo entero: El semáforo es un número entero.
Registrar semáforo: además de un valor entero s.value (recuento), cada semáforo S también tiene una cola de espera de proceso s.L, cada uno de los cuales está bloqueado en el semáforo La identidad del proceso.
Semáforo binario: Sólo el semáforo puede tomar el valor 0 o 1.
Cada semáforo debe registrar al menos dos datos: el valor del semáforo y la cola de procesos que esperan el semáforo. Su tipo se define de la siguiente manera: (expresado en lenguaje tipo PASCAL)
Semaphore = record
Valor: entero;
Cola: ^pcb; p >
Fin;
Entre ellos, PCB es el bloque de control de procesos, que es una estructura de datos establecida por el sistema operativo para cada proceso.
s.value & gt=0, s.queue está vacío
Valor & lt0, el valor absoluto de s.value es el número de procesos esperando en s.queue;
p>
Características
Editar
En resumen, las características del semáforo son: el semáforo es un número entero no negativo (el número de automóviles) , y todos los subprocesos/procesos que lo atraviesen (Car) reducirán este número entero en uno (por supuesto, para utilizar recursos). Cuando el valor entero es cero, todos los subprocesos que intenten pasarlo estarán en estado de espera. En el semáforo definimos dos operaciones: esperar y soltar. Cuando un hilo llama a la operación de espera, adquiere el recurso y disminuye el semáforo en 1, o espera hasta que el semáforo sea mayor o igual a 1. La liberación es en realidad una operación adicional al semáforo, que corresponde a la salida del vehículo del estacionamiento. Esta operación se denomina "liberación" porque se liberan los recursos custodiados por el semáforo.
Modo de ejecución
Editar
El semáforo tiene cuatro operaciones (incluida
1.initialize, también llamada create int SEM_init (SEM_ t * SEM, int pshared, unsigned int value);
2.wait, también llamado suspender int SEM _ wait(SEM _ t * SEM);
3 .signal o post); int SEM_post(SEM_t*SEM);
4.destroy int SEM_destruction(SEM_t*SEM);[1]
Establecer
Editar
Al igual que * * * la memoria compartida, el sistema también necesita personalizar una serie de funciones operativas propietarias (semget, semctl, etc.) para el conjunto de semáforos. Se puede utilizar el comando del sistema ipcs para ver el estado actual del sistema IPC. y use el parámetro -s después del comando.
Utilice la función semget para crear u obtener una ID de conjunto de semáforos. El prototipo de esta función es el siguiente:
# include & ltsys/shm .
int semget(key_t key, int nsems, int flag);
La clave de parámetro en la función se utiliza para convertir en un identificador, y cada objeto IPC corresponde a una clave. Al crear un nuevo segmento de memoria compartida * * *, al campo de modo en la estructura ipc_perm se le asigna el bit de permiso correspondiente al indicador de parámetro, y el valor de inicialización shmid_ds del conjunto de semáforos correspondiente se muestra en la Tabla 1.
Tabla de valores de inicialización de la estructura Shmid_ds
Datos de la estructura Ipc_perm
Información básica
Datos de la estructura Ipc_perm
Información básica
Tiempo (_ o)
Sem_nsems
Nsems
Sem_ctime
Valor actual del sistema
El parámetro nsems es un valor mayor o igual a 0, que indica la cantidad de recursos disponibles en el conjunto de semáforos (cuando se crea el semáforo). Al abrir un conjunto de semáforos existente, el valor de este parámetro es 0. La función devuelve el identificador del conjunto de semáforos (un número entero mayor o igual a 0) en caso de éxito, o –1 en caso de error. La función semop se utiliza para operar el conjunto de semáforos. El prototipo de esta función es el siguiente:
# include & ltsys/SEM .
int semop(int semid, struct sembuf semoparray[], size_t nops);
El parámetro semid en la función es el identificador de semáforo devuelto por la función semget, y el parámetro nops representa el número de elementos en la matriz a la que apunta el parámetro semoparray. El parámetro semoparray es un puntero de matriz del tipo de estructura struct sembuf. La estructura sembuf se utiliza para explicar la operación a realizar. Se define de la siguiente manera:
Estructura sembuf{
. sem_num corto sin firmar
sem_op corto
sem_fg corto
}
En la estructura sembuf, sem_num es un recurso en el conjunto de semáforos correspondiente, por lo que su valor es un número entero de 0 al número total de recursos en el conjunto de semáforos correspondiente (ipc_perm.sem_nsems). Sem_op representa la operación a realizar y sem_flg describe el comportamiento de la función semop. El valor de sem_op es un número entero, como se muestra en la Tabla 2. La Tabla 2 enumera los valores detallados de sem_op y las operaciones correspondientes.
Descripción detallada del valor de sem_op
Sem_op
Ejercicio
Número positivo
Libera la cantidad correspondiente de recursos Y agregue el valor de sem_op al valor del semáforo.
El proceso se bloqueará hasta que el valor correspondiente del semáforo sea 0. Cuando el semáforo ya es 0, la función regresa inmediatamente. Si el valor del semáforo no es 0, la acción de la función se determina en función del bit IPC_NOWAIT de sem_flg. Si Sem_flg especifica IPC_NOWAIT, la función semop devuelve un error EAGAIN. Sem_flg no especifica IPC_NOWAIT, luego agrega 1 al valor semncnt del semáforo y luego el proceso se bloquea hasta que ocurre la siguiente situación. Cuando el semáforo es 0, se resta 1 del valor semzcnt del semáforo y la función semop regresa correctamente. El semáforo se elimina (solo el superusuario o el proceso que creó el usuario tiene este permiso) y la función smeop devuelve EIDRM con un error, el proceso captura la señal y devuelve la señal de la función de procesamiento de señales; En este caso, el valor semncnt de este semáforo se reduce en 1 y la función semop regresa a EINTR con un error.
Número negativo
Solicita recursos con el valor absoluto de sem_op.
Si la solicitud puede satisfacerse con la cantidad correspondiente de recursos, el valor absoluto de SEM_op se resta del valor del semáforo y la función regresa exitosamente. Esta operación está relacionada con sem_flg cuando la cantidad correspondiente de recursos no puede satisfacer la solicitud. Si Sem_flg especifica IPC_NOWAIT, la función semop devuelve un error EAGAIN. Si sem_flg no especifica IPC_NOWAIT, el valor semncnt del semáforo se incrementa en 1 y el proceso se suspende hasta que ocurra lo siguiente: el valor absoluto de sem_op se resta del valor del semáforo cuando el número correspondiente de recursos puede satisfacer la solicitud. . Regreso exitoso; el semáforo se elimina (solo el superusuario o el proceso que creó el usuario tiene este permiso), la función smeop devuelve EIDRM en caso de error: el proceso captura la señal y regresa de la función de procesamiento de señales. El valor semncnt del semáforo disminuye en 1. La función semop devuelve EINTR cuando se produce un error.
Proceso básico
Editar
El siguiente ejemplo demuestra el proceso básico de operación del semáforo. La función Semget se usa para crear un conjunto de semáforos y la función semop se usa para realizar una operación de liberación de recursos en este conjunto de semáforos. Y use el comando en el shell para ver el estado del IPC del sistema.
(1) Edite el programa en el editor vi.
Listado de Programas 14-10 create_sem.c usa la función semget para crear un semáforo.
# incluir & ltsys/types h & gt;
# incluir & ltsys/IPC .
# incluir & ltsys/SEM . h & gt;
# incluir & ltstdio.h & gt
# incluir & ltstdlib.h & gt
int main( void)
{
int sem _ id
int nsems = 1;
int flags = 0666
struct sembuf buf p>
sem_id = semget(IPC_PRIVATE, nsems, flags); /*Crear un nuevo conjunto de semáforos*/
if(SEM_id<0){
perror("SEM get");
Salir(1);
}
/*Emite el identificador del conjunto de semáforos correspondiente*/ p>
printf( "Semáforo creado exitosamente: %d\n ", SEM _ id);
buf . SEM_num = 0 /*Definir operación del semáforo*/
buf. ;/*Realizar operación de liberación de recursos*/
buf.sem_flg = IPC_NOWAIT/*Definir el comportamiento de la función semop*/
if ((semop(sem_id,&buf,nsems) )<0) {/*Realizar operación*/
error("semop");
Salir( 1);
}
Sistema ("IPCS-s"); /*Ver el estado del IPC del sistema*/
Salir (0);
}
(2) Compile el programa en vmware, de la siguiente manera:
gcc -o a.o testc_semaphore.c
(3) En Ejecute el programa en el shell de la siguiente manera:
.
/a3.o
Semáforo creado exitosamente: 0
-Matriz de semáforo-
Licencia de medio propietario clave
0x 000000000 0 zcr 666 1
En el programa anterior, se crea un conjunto de semáforos utilizando la función semget y el número de recursos en el conjunto de semáforos se define como 1. Luego, use la función semop para liberar el recurso. Al final del programa, use el comando de shell ipcs para verificar el estado del IPC del sistema.
%Nota: El comando ipcs parámetro -s identifica el estado del conjunto de semáforos del sistema IPC.
Espero que te pueda ayudar, y espero que puedas adoptarlo con satisfacción.