threads
Diferencias
Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anteriorRevisión previaPróxima revisión | Revisión previa | ||
| threads [2018/06/26 13:54] – [Equivalencia entre herramientas de sincronización] lmateu | threads [2018/07/06 00:04] (actual) – [Productor/consumidor] lmateu | ||
|---|---|---|---|
| Línea 359: | Línea 359: | ||
| } | } | ||
| | | ||
| - | void consumidor(Buffer | + | void *consumidor(void *ptr) { // porque se usa en pthread_create |
| + | Buffer *buf= ptr; | ||
| for (;;) { | for (;;) { | ||
| Cuadro *cuadro= get(buf); | Cuadro *cuadro= get(buf); | ||
| Línea 366: | Línea 367: | ||
| mostrarCuadro(cuadro); | mostrarCuadro(cuadro); | ||
| } | } | ||
| + | return NULL; | ||
| } | } | ||
| | | ||
| void reproducirVideo() { | void reproducirVideo() { | ||
| Buffer *buf= nuevoBuffer(60); | Buffer *buf= nuevoBuffer(60); | ||
| - | | + | |
| - | pthread_create(& | + | pthread_create(& |
| productor(buf); | productor(buf); | ||
| - | pthread_join(pid, NULL); | + | pthread_join(t, NULL); |
| } | } | ||
| </ | </ | ||
| Línea 912: | Línea 914: | ||
| El problema de esta solución es que los lectores se pueden concertar para entrar y | El problema de esta solución es que los lectores se pueden concertar para entrar y | ||
| salir alternadamente, | salir alternadamente, | ||
| - | así en // | + | así en // |
| - | + | que evitan la hambruna. | |
| - | === Segunda solución === | + | |
| - | + | ||
| - | Esta solución evita la hambruna por medio de la metáfora de la isapre. | + | |
| - | isapre los threads deben pedir un número antes de realizar su operación. | + | |
| - | solo puede entrar a realizar su operación cuando el número que aparece en un visor | + | |
| - | coincide con el número que se le asignó. | + | |
| - | se satisfacen en orden FIFO (//first in first out//), aunque las lecturas se hacen | + | |
| - | en paralelo y por lo tanto las salidas pueden ocurrir en un orden no FIFO. | + | |
| - | + | ||
| - | En esta solución | + | |
| - | porque una vez que el escritor recibe su número, ningún otro lector podrá entrar | + | |
| - | al diccionario. | + | |
| - | que salir y será el turno del escritor. | + | |
| - | + | ||
| - | < | + | |
| - | pthread_mutex_t mutex; | + | |
| - | pthread_cond_t cond; | + | |
| - | int readers= 0; | + | |
| - | int display= 0; | + | |
| - | int serial= 0; | + | |
| - | + | ||
| - | void enterRead() { | + | |
| - | int myNum; | + | |
| - | pthread_mutex_lock(& | + | |
| - | myNum= = serial++; | + | |
| - | while (myNum!=display) | + | |
| - | pthread_cond_wait(& | + | |
| - | readers++; | + | |
| - | display++; | + | |
| - | pthread_cond_broadcast(& | + | |
| - | pthread_mutex_unlock(& | + | |
| - | } | + | |
| - | + | ||
| - | void exitRead() { | + | |
| - | pthread_mutex_lock(& | + | |
| - | readers--; | + | |
| - | if (readers==0) | + | |
| - | pthread_cond_broadcast(& | + | |
| - | pthread_mutex_unlock(& | + | |
| - | } | + | |
| - | + | ||
| - | void enterWrite() { | + | |
| - | int myNum; | + | |
| - | pthread_mutex_lock(& | + | |
| - | myNum= serial++; | + | |
| - | while (readers> | + | |
| - | pthread_cond_wait(& | + | |
| - | pthread_mutex_unlock(& | + | |
| - | } | + | |
| - | + | ||
| - | void exitWrite() { | + | |
| - | pthread_mutex_lock(& | + | |
| - | display++; | + | |
| - | pthread_cond_broadcast(& | + | |
| - | pthread_mutex_unlock(& | + | |
| - | } | + | |
| - | </ | + | |
| - | + | ||
| - | Nota: el broadcast se necesita acá porque el incremento de display podría gatillar | + | |
| - | que un lector que se encontraba esperando ahora puede entrar. | + | |
| - | + | ||
| - | // | + | |
| - | Supongamos que hay un escritor trabajando y n lectores esperando. | + | |
| - | caso se pueden requerir hasta O(n^2) cambios de thread a thread para que todos los lectores comiencen | + | |
| - | a trabajar. | + | |
threads.1530021279.txt.gz · Última modificación: por lmateu
