2011-03-19 12 views
5

Hace un tiempo estaba pensando en cómo implementar varias primitivas de sincronización en términos de la otra. Por ejemplo, en pthreads obtienes mutexes y variables de condición, y a partir de estos puedes construir semáforos.¿Cómo se puede implementar una variable de condición usando semáforos?

En la API de Windows (o al menos, versiones anteriores de la API de Windows) hay mutexes y semáforos, pero no variables de condición. Creo que debería ser posible construir variables de condición a partir de mutexes y semáforos, pero por mi vida no puedo pensar en una forma de hacerlo.

¿Alguien sabe de una buena construcción para hacer esto?

Respuesta

0

Una forma de implementar X semáforos determinados es agregar un proceso de servidor al sistema, usar semáforos para comunicarse con él, y hacer que el proceso haga todo el trabajo de implementar X. Como ejercicio académico, esto podría ser hacer trampa , pero hace el trabajo, y puede ser más robusto a la mala conducta de los procesos del cliente o a su muerte repentina.

+0

Umm, a menos que "semáforo" signifique algo completamente diferente en las API de Windows, no es algo con lo que se comunique. – Theo

+0

Un proceso puede establecer un semáforo y otro proceso puede probarlo para ver si se ha configurado o no. Dos máquinas pueden comunicar mensajes arbitrarios al probar y configurar las tensiones en un par de cables. Dos procesos pueden comunicar mensajes arbitrarios al probar y establecer el estado de los semáforos. En la práctica, probablemente use los semáforos solo para regular el acceso a la memoria compartida, pero considero ambos casos como comunicación, incluso si en el segundo caso, todo lo que está comunicando es "OK", puede leer la memoria compartida ahora. – mcdowella

1

Me puede estar faltando algo aquí, pero parece haber una manera más simple de implementar una condición desde un semáforo y bloqueo que la manera descrita en el documento.

class Condition { 
    sem_t m_sem; 
    int m_waiters; 
    int m_signals; 
    pthread_mutex_t *m_mutex; 
public: 

    Condition(pthread_mutex_t *_mutex){ 
     sem_init(&this->m_sem,0,0); 
     this->m_waiters = 0; 
     this->m_signals = 0; 
     this->m_mutex = _mutex; 
    } 
    ~Condition(){} 
    void wait(); 
    void signal(); 
    void broadcast(); 
}; 

void Condition::wait() { 
    this->m_waiters++; 
    pthread_mutex_unlock(this->m_mutex); 
    sem_wait(&this->m_sem); 
    pthread_mutex_lock(this->m_mutex); 
    this->m_waiters--; 
    this->m_signals--; 
} 

void Condition::signal() { 
    pthread_mutex_lock(this->m_mutex); 
    if (this->m_waiters && (this->m_waiters > this->m_signals)) { 
     sem_post(&this->m_sem); 
     this->m_signals++; 
    } 
    pthread_mutex_unlock(this->m_mutex); 
} 
+1

Creo que debería funcionar en su mayoría, pero teóricamente, su último mesero podría ser interceptado entre sem_wait y pthread_mutex_lock por una señal de llamada de subprocesos, y eso arruinaría el valor de su semáforo. Es complicado hacer las cosas bien para todos los entrelazados posibles de hilos. – PSkocik

Cuestiones relacionadas