2008-10-30 10 views
5

Tengo una única interfaz HW que quiero usar desde dos aplicaciones (procesos) en la misma estación de trabajo. El HW requiere una sola llamada de inicialización, luego, cualquiera de las aplicaciones usa la misma función (en la misma biblioteca) para hacer muchas transacciones con el HW.¿Cómo sincronizo dos procesos?

Así que cada aplicación debe actuar de esta manera:

main() 
    // I don't know if another app already init'ed the HW 
    ret = hw_init_lock(non-blocking) 

    if ret = OK 
     // no one else has done this, I have to 
     init_hw() 
    else 
     //someone else has already init'ed the HW, I gotta make sure it stays that way 
     //as long as I'm alive 
     increment_hw_init_ref_counter() 

    hw_trans_lock(blocking) 
    hw_trans() 
    hw_trans_unlock() 
    .... 

    //exit app, uninit hw if we are last out 
    ret = decrement_hw_init_ref_counter() 
    if ret == 0 
     uninit_hw() 

    exit(0) 

Cuál es el mecanismo que puedo utilizar en la cerradura y de referencia llamadas de conteo que se comparte entre dos aplicaciones? Estoy pensando en tuberías con nombre, es decir, mkfifo().

Respuesta

2

Dado que solo necesita un número de semáforo de uno, basta un mutex.

+4

semáforos POSIX pueden ser compartidos a través de procesos no relacionados, mientras que los mutex pthread no puede. – ephemient

9

POSIX semaphore es el camino a seguir. Puesto que usted quiere compartir el mismo semáforo través de los procesos, es necesario utilizar un semáforo nombrado .:

Un semáforo con nombre se identifica por un nombre de la forma/algunnombre. Dos procesos pueden operar en el mismo semáforo con nombre pasando el mismo nombre a sem_open (3).

1

que asumen que

... que se comparte entre dos aplicaciones?

significa que desea que estas dos cosas se ejecuten como procesos separados? Si eso no es cierto, y se están ejecutando como un proceso único (con múltiples hilos), entonces las sugerencias de semáforos y mutex son la mejor opción y deberían ser bastante sencillas.

Tenga en cuenta que la respuesta dependerá exactamente de cómo esté accediendo a este hardware. Por ejemplo, si está expuesto a través de un archivo, se puede usar el bloqueo de archivos normal.

Sin embargo, si está intentando sincronizar el acceso al hardware en dos procesos, eso es algo diferente. Supongo que lo primero que debe decir es que será más fácil sincronizar, si puede, tener un único proceso a cargo del acceso al hardware. En este modelo, es posible que tenga un proceso que actúe como servidor para el hardware: acepte solicitudes de otros procesos y realice las lecturas y escrituras en su nombre. Casi cualquier forma de comunicación entre procesos será adecuada, pero para simplificar algo como la cola de mensajes (link) puede ser apropiado con una estructura de datos apropiada (por ejemplo, un indicador para indicar si se trata de una operación de lectura o escritura, desplazamiento de la dirección base de su hardware, número de bytes, búfer (en caso de escribir)

Si no es apropiado poner todo el acceso directo al hardware en un único proceso, entonces deberá utilizar un esquema de sincronización adecuado. Investigaría el uso de cualquiera de los bloqueos de archivos (e implementaría un esquema mutex rudimentario) o usar semáforos con nombre (como ha sugerido albertb)

4

Las semáforos y mutexes/variables de condición son buenas primitivas de muy alto rendimiento que son apropiadas para usar entre hilos o entre procesos.

Todos estos se basan en la idea (y generalmente, en la realidad) de probar y establecer u otras operaciones atómicas realizadas en la memoria compartida.

Si espera distribuir sus procesos a través de la red, los semáforos y mutexes pueden no ser adecuados para usted, solo funcionan en una sola máquina. Las tuberías y tomas son, en general, extensibles a la red.

Un breve resumen de mutexes, variables de condición y semáforos:

objetos mutex

Un mutex es una primitiva que puede ser bloqueado o desbloqueado. El proceso/hilo que lo bloqueó debe ser el que lo desbloquee. Este aspecto de propiedad permite que el sistema operativo aplique algunas optimizaciones interesantes, como herencia de prioridad y protocolo de techo de prioridad (para evitar la inversión de prioridad). sin embargo,, el mutex no tiene un recuento asociado. No puede bloquear un mutex ya bloqueado, en general, y retener la memoria que estaba "bloqueado dos veces" (hay algunas extensiones que permiten esto, creo, pero no están disponibles en todas partes)

Variables de condición

Un mutex es ideal para ... bueno, MUTual EXclusion. Pero, ¿qué sucede si necesita bloquear una condición asociada con el objeto al que tiene exclusión mutua? Para esto, usa una variable de condición, o CV. Un CV está asociado con un mutex. Por ejemplo, supongamos que tengo una cola de datos de entrada a la que mis procesos quieren acceder. Uno agarra el mutex para que pueda mirar la cola sin temor a interferencias. Sin embargo, encuentra la cola vacía y quiere esperar a que algo entre en la cola. Por lo tanto, espera en la variable de condición "cola no vacía". La parte interesante aquí es que, debido a que el CV está asociado con el mutex, el mutex obtiene automáticamente vuelto a adquirir una vez que se señala la variable de condición. Por lo tanto, una vez que el proceso se despierta después de esperar en el CV, sabe que tiene acceso exclusivo nuevamente a la cola. Lo que hace no es saber si la cola realmente tiene algo que ver -quizá dos procesos esperaron en el CV-, una cosa entró, y la primera prioridad entró y quitó la "cosa" antes de que despertara la segunda cosa arriba. Por lo tanto, cada vez que utilice un CV, es necesario volver a comprobar la condición, así:

mutex_enter(m); 
while (! condition) { 
    cond_wait(m, c); // drop mutex lock; wait on cv; reacquire mutex 
} 
//processing related to condition 
mutex_exit(m); 

semáforos

OK, esto es mutex y variables de condición. Los semáforos son más simples. Se pueden incrementar y disminuir mediante cualquier proceso. Tienen memoria, cuentan, por lo que puedes usarlas para determinar cuántas de una condición han ocurrido. No ocurre lo mismo con las variables de condición. Además, como los semáforos se pueden disminuir en un proceso y aumentar en otro, no tienen el aspecto de propiedad, por lo que no es posible heredar la prioridad ni evitar la inversión prioritaria.

Ahora, finalmente, todos estos mecanismos requieren memoria compartida para una implementación eficiente. Esto puede estar bien para usted, pero tenga en cuenta que si cree que su aplicación se puede distribuir finalmente, entonces mutexes, variables de condición y semáforos pueden no ser para usted. Las tuberías y tomas de corriente, aunque tienen una sobrecarga mucho mayor, tienen la posibilidad de extenderse por la red de manera bastante sencilla.

Cuestiones relacionadas