1. Acerca de las carreras
Si dos procesos abren el dispositivo al mismo tiempo para escribir datos, será nuevo cuando el proceso A escriba datos. Aplique una memoria de dispositivo rápida y agregue un nuevo cuanto a la tabla de enlace de datos de desarrollo del dispositivo, de modo que el puntero apunte al nuevo bloque de memoria del dispositivo, y la operación de escritura del proceso B también tenga la misma operación, por lo que si no realiza ninguna modificación del controlador, el dispositivo es de dos. Cuando los procesos se abren al mismo tiempo, los dos procesos tienen la misma información de la tabla de enlace de datos del dispositivo, y se modificarán los mismos datos. Es obvio que los datos creados por la primera operación serán sobrescritos por el proceso posterior, que es el estado de carrera.
Sin embargo, el argumento menos positivo es que esto no ocurre en un solo procesador porque el código que se ejecuta en el kernel no es preventivo, lo que significa que el procesador solo puede procesar un código a la vez. Pero puede suceder un sistema multiprocesador.
LINUX ofrece una solución de carrera:
1) semáforo semáforo, utilizado para la exclusión mutua
#include
Es muy simple, es decir Se debe definir una etiqueta en el bloque de datos que se debe evitar. Cuando se usa un proceso, la bandera se establece en 0, lo que indica que la señal ya está ocupada y ya no se puede usar. Todos los procesos deben primero verificar la etiqueta si desean acceder al bloque de datos. Si es 0, significa que un proceso está ocupando, debe esperar.
Por lo tanto, hay una etiqueta de semáforo en la estructura de datos Scull_Dev de scull0.
Pero el semáforo es manejado por el kernel, porque queremos que el proceso sea un semáforo, si se usa el semáforo, el proceso debe ser entregado al kernel, esperando, no en bucle por nosotros mismos. Revisa y espera los semáforos.
ok, ya que tiene que ser entregado a la administración del kernel, el semáforo debe ser inicializado.
sema_init (&scull_devices.sem, 1); //; Registre un semáforo, inicializado en 1, lo que indica que está disponible.
Cuando necesite obtener un semáforo, llame a down_interruptable (&sem), suelte el semáforo (&sem), active y active el proceso que está esperando el semáforo.
if (down_interruptable (&dev- > sem)) return -ERESTARTSYS; //; Si falla, devuélvelo directamente, no puedo llamar (&sem) //; operaciones de datos ...
arriba (&dev- > sem);
Tenga en cuenta que debe tener cuidado con el uso de semáforos, visible si un proceso contiene un semáforo y falla cuando libera el semáforo Si lo haces, otros procesos se bloquearán.
Además, como el semáforo hará que el proceso se duerma, el semáforo no se puede aplicar en el procesamiento de interrupción.
2) Bloqueo
Como puede ver, utilizando un semáforo, si un proceso contiene un semáforo, otro proceso se pondrá en suspensión. En muchos casos, el proceso no necesita esperar a la suspensión. Por ejemplo, no se permite que el procesamiento de interrupción entre en suspensión, o en algunos casos, es simplemente para comprobar si los datos públicos están ocupados por otros procesos. Si está ocupado, se volverá a probar hasta que se pueda usar. Utilice un spinlock. Por supuesto, cuando se utiliza el bloqueo de giro, el procesador está ocupado, por lo que el bloqueo de giro es adecuado para mantener los datos durante un tiempo relativamente corto, y es absolutamente imposible ir a dormir cuando se mantiene el bloqueo.
#include
spinlock_t my_lock = SPIN_LOCK_UNLOCKED; o spin_lock_init (&my_lock); declara /crea un bloqueo
spin_lock (spinlock_t * my_lock); obtiene el bloqueo proporcionado Si el bloqueo está ocupado, gira hasta que el bloqueo está disponible. Cuando el spin_lock vuelve, la función de llamada mantiene el bloqueo hasta que se libera spin_unlock (spinlock_t * my_lock); el bloqueo se libera
2 Acerca del bloqueo y el no bloqueo < Br>
2.1 Acerca del bloqueo
Hay un problema con la llamada de lectura. Cuando el dispositivo no tiene datos para leer, hay dos maneras de resolverlo. Una es evitar que la falla de lectura directa salte. El segundo es bloquear la operación de lectura, el proceso se pone en suspensión y se activa cuando hay datos.
Discuta el bloqueo de E /S aquí para controlar el sueño y despertarse.
La suspensión se produce cuando un proceso debe esperar un evento, debe suspenderse temporalmente, dejar salir la CPU y despertarse después de que llegue el evento.
Una forma de controlar la suspensión es agregar un proceso a la cola de espera:
1) Primero debe declarar e inicializar una entrada de cola de espera.
#include
wait_queue_head_t my_queue;
init_waitqueue_head (&my_queue);
Si está esperando una cola de espera global estática, puede usar las dos definiciones anteriores en lugar de
DECLARE_WAIT_QUEUE_HEAD ( My_queue); //la declaración estática se inicializará automáticamente en el momento de la compilación
2) usa el elemento de la cola de espera inicializada
call interrupt30_and_on (&my_queue) cuando necesite unirse a la cola de espera del kernel; o sleep_on (&my_queue)
Cuando se requiere la activación, llame a wake_up_interruptible (&my_queue); o wake_up (&my_queue)
3) interruptible_sleep_on () defectuoso
a. La carrera resultante:
Para comprender el posible estado de carrera causado por interruptible_sleep_on () y otras funciones sleep_on, necesita saber más sobre la implementación de interruptible_sleep_on ().
La cola de espera es en realidad una lista de colas. Los datos en la lista enlazada son del tipo wait_queue_t. La interruptible_sleep_on () simplificada interna es probablemente así:
#include
wait_queue_t wait; //; Definir una cola de espera
init_wait_queue_entry (&wait, current); //; Inicializar
current- > state = TASK_INTERRUPTILBE; //; Establecer en estado de suspensión, entrará Sleep
add_wait_queue (&my_queue, &wait); //; Agrega el elemento de la cola de espera que definimos a esta cola de espera
schedule (); //;
remove_wait_queue (&my_queue, &wait); //; El evento llega, schedule () devuelve
La carrera ocurre en current- > state = TASK_INTERRUPTIBLE and schedule () En algunos casos, cuando el controlador está listo para irse a dormir, es decir, cuando se ha establecido el estado actual->, puede haber solo llegada de datos. En este momento, wake_up no activará el proceso que no se ha puesto en suspensión, lo que puede ocasionar El proceso ha estado durmiendo porque no ha respondido al despertar, generando así esta competencia. Esta carrera es muy propenso. La solución es no usar interruptible_sleep_on (), sino usar su implementación interna directamente.
Ejemplo:
#include
wait_queue_t wait; //; Definir una cola de espera
init_wait_queue_entry (&wait, current); //; Inicializar
add_wait_queue (&my_queue, &wait); //; Agregue el elemento de cola de espera que definimos a esta cola de espera
while (1) {
current- > state = TASK_INTERRUPTILBE; //; configurado para dormir, se irá a dormir
if (short_head! = short_tail) break; //; prueba si hay datos llegando, si los hay, saltan
schedule (); //; Real to sleep
}
set_current_state (TASK_RUNNING);
remove_wait_queue (&my_queue, &wait); //; El evento llega, schedule () devuelve
De hecho, podemos hacer estas cosas complicadas sin el kernel. El núcleo define una macro
wait_event_interruptible (wq, condition); o wait_event (wq, Condición) condición es la condición de la prueba
pasos de configuración de servicios de Telnet son las siguientes: a, paquete de instalación de
¿Se bloqueará el servidor Linux? Por supuesto, he estado expuesto a cierto tipo de servidor. Después
partición del disco en Linux, formateo del sistema de archivos y dispositivo raid - comparando el fo
Descarga NetBeans Toma netbeans-7.0beta2-ml-javaee-linux.sh como ejemplo #sh netbeans-7.0beta2
Dos formas de instalar el sistema SUSE Linux10 desde el disco duro
Cómo lograr la transferencia de archivos de Linux y Windows
Sistema de archivos cargando durante el proceso de arranque de Linux
Tome el sistema de facturación con clusters Linux
Tutorial estándar de entrada /salida de Linux
Configurar GAppProxy tutorial en el sistema Linux
Dispositivo modelo bus, driver, tutorial básico del dispositivo
Hablando del problema de partición del sistema Linux
Conceptos básicos sobre el uso de la familia de funciones de Linux exec
Consejos de Linux SecureCRT para cargar y descargar archivos
La copia de seguridad del plan win8 del plan utiliza el tutorial
Win7 sistema abrir archivo PDF error asociado cómo hacerlo
Win8 Enciclopedia 44: cómo encontrar rápidamente el archivo oculto
Forbidden win7 /8 actualización automática win10 gráficos tutorial
¿Qué debo hacer si no se puede abrir la personalización del sistema Win10?
Vista no reconoce cómo se resuelve la cámara digital
Explicación completa de los conocimientos de arranque de Windows 7 (1)
¿Qué debo hacer si el sistema de Win 7 limpia el registro y no puedo conectarme a Internet?