Autor
|
Tema: Problema con buzones (Leído 2,027 veces)
|
snowspring
Desconectado
Mensajes: 12
|
Hola! Estaba haciendo un ejercicio en el cual hay que sincronizar varios procesos y que estos procesos sigan sincronizandose (en este caso los procesos son unos semaforos que tienen que ir cambiando de color de forma logica osea cuando uno este en verde el otro no puede estar en verde y viceversa) hasta que se pulse ctrl-c. El caso es que mi idea era realizar esta sincronizacion con un buzon IPC pero el problema viene que despues de la primera interaccion del bucle infinito el programa ya no vuelve a cambiar de color los semaforos, es decir, si inicialmente los semaforos estan uno a verde y otro a rojo el programa entra en el bucle y cambia el verde a rojo y el rojo a verde SOLO 1 vez (el objetivo es que este cambio se produzca continuamente). Dejo aqui el codigo: int buzon = atoi(p_memC +334); //el buzon esta correctamente inicializado y guardado en memoria compartida int envio, recibo; struct tipo_mensaje { long tipo; char mensaje[20]; }mensaje; while(1){ if(*(p_memC+274) == VERDE) //aqui se comprueba el estado del semaforo horizontal, el estado lo actualiza automaticamente luz_sem { luz_sem(HORIZONTAL, ROJO); strcpy(mensaje. mensaje, "HORIZ ROJO"); mensaje.tipo = HORIZONTALROJO; if((envio = msgsnd(buzon, &mensaje, sizeof(struct tipo_mensaje)-sizeof(long), MSG_NOERROR))==-1) { } }else if(*(p_memC+274) == ROJO){ mensaje.tipo=VERTICALROJO; if((recibo=msgrcv(buzon, &mensaje, sizeof(struct tipo_mensaje)-sizeof(long), mensaje.tipo, MSG_NOERROR))==-1) { } luz_sem(HORIZONTAL, VERDE); //esta es una funcion que esta comprobada que funciona correctamente para cambiar el semaforo de color }else if(*(p_memC+275) == VERDE){ //aqui se comprueba el estado del semaforo horizontal, el estado lo actualiza automaticamente luz_sem luz_sem(VERTICAL, ROJO); strcpy(mensaje. mensaje, "VERTICAL ROJO"); mensaje.tipo = VERTICALROJO; if((envio = msgsnd(buzon, &mensaje, sizeof(struct tipo_mensaje)-sizeof(long), MSG_NOERROR))==-1) { } }else if(*(p_memC+275) == ROJO){ mensaje.tipo=HORIZONTALROJO; if((recibo=msgrcv(buzon, &mensaje, sizeof(struct tipo_mensaje)-sizeof(long), mensaje.tipo, MSG_NOERROR))==-1) { } luz_sem(VERTICAL, VERDE); } }
Muchas gracias!
|
|
|
En línea
|
|
|
|
CalgaryCorpus
|
Existe un valor distinto de verde o rojo para los semaforos?
Los primeros 2 ifs me dan la impresion que cubren todos los casos para 1 semaforo y por lo tanto los otros 2 ifs nunca se van a ejecutar.
|
|
|
En línea
|
|
|
|
dijsktra
Desconectado
Mensajes: 110
Mr Edsger Dijsktra (Tribute to)
|
Hola! Estaba haciendo un ejercicio en el cual hay que sincronizar varios procesos y que estos procesos sigan sincronizandose (en este caso los procesos son unos semaforos que tienen que ir cambiando de color de forma logica osea cuando uno este en verde el otro no puede estar en verde y viceversa) hasta que se pulse ctrl-c. El caso es que mi idea era realizar esta sincronizacion con un buzon IPC [...]
Muchas gracias!
A ver, la forma "natural" de hacerlo es con semáforos, no con lo que tu llamas "buzones"... (Creo que con lo que te refieres a eso es a colas, pero bueno...) En cuanto pueda, hago una solución de ese modo Aquí hay una propuesta de simulación. Creo que deberías empezar por threads, en vez de , como creo, haces con IPC y fork(), al estar incompleto el código, no puedo interpretar.... /* Syncrhonized red-green semaphores using semaphores... Safety Invariant: 0 <= one_sem + two_sem <= 1 */ #include <pthread.h> #include <semaphore.h> #include <stdlib.h> // exit #include <stdio.h> // print #include <unistd.h> // sleep sem_t one_sem; sem_t two_sem; void* one_thread(void *arg) { for( ; 1 ; ) { if (sem_wait(&one_sem)) { } sleep(2); if (sem_post(&two_sem)) { } } } void* two_thread(void *arg) { for( ; 1 ; ) { if (sem_wait(&two_sem)) { } printf("\t\t\t\ttwo: \t\tRED\n"); sleep(2); if (sem_post(&one_sem)) { } printf("\t\t\t\ttwo: \t\tGREEN\n"); } } int main(int argc, char **args) { pthread_t one,two; sem_init(&one_sem,0,1); sem_init(&two_sem,0,0); if (pthread_create(&one, NULL, one_thread, NULL)) { } if (pthread_create(&two, NULL, two_thread, NULL)) { } if (!pthread_join(one,NULL)) { } if (!pthread_join(two,NULL)) { } }
Y la salida, (el efecto temporal no sale en esta página estática Web, claro. Deberias ver que se sincronizan al mismo tiempo. Correlo en tu terminal.) gcc redgreen.c -lpthread -o main && ./main one: RED one: GREEN two: RED two: GREEN one: RED one: GREEN two: RED two: GREEN one: RED one: GREEN two: RED two: GREEN one: RED one: GREEN two: RED two: GREEN one: RED one: GREEN two: RED two: GREEN one: RED one: GREEN two: RED two: GREEN one: RED one: GREEN two: RED two: GREEN one: RED
|
|
« Última modificación: 10 Abril 2019, 14:37 pm por dijsktra »
|
En línea
|
Si la depuración es el proceso de eliminar fallos en el software, entonces programar debe ser el proceso de ponerlos dentro. (Edsger Dijsktra)
|
|
|
dijsktra
Desconectado
Mensajes: 110
Mr Edsger Dijsktra (Tribute to)
|
Lo prometido es deuda. Aqui tienes una implementación de sincronización con colas System V. Comentarios - Podemos emular una especie de semáforo distribuido con colas. Las operaciones P(s) y V(s) son las correspondeintes a rcv(q) y snd(q). Eso si, expresado en C, es un poco críptico, ya que tenemos que ver siempre el retorno de la llamada al sistema
- Al ser utilizado como señalización, el mensaje no precisa de datos. no se precisa comunicar ningún dato, el mismo acto de envío y recepción es suficiente. De ahí que el msg.txt sea de tamñao 0, no es necesario poner "LUZ VERDE" o "LUZ ROJA"...
/* Syncrhonized red-green semaphores using queues a queue can act as a distributed semaphore */ #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> // exit #include <stdio.h> // print #include <unistd.h> // sleep int msq1; int msq2; // queue descriptors... typedef struct msgbuf { long mtype; /* message type, must be > 0 */ char mtext[0]; /* message data */ } msg; void one_process() { struct msgbuf msg = { 1 }; for( ; 1 ; ) { if (msgrcv(msq1,(void *)&msg,sizeof(msg.mtext),0,0)==-1) { } sleep(2); if (msgsnd(msq2,(void *)&msg,sizeof(msg.mtext),0)) { } } } void two_process() { struct msgbuf msg = { 1 }; for( ; 1 ; ) { if (msgrcv(msq2,(void *)&msg,sizeof(msg.mtext),0,0)==-1) { } printf("\t\t\t\ttwo: \t\tRED\n"); sleep(2); if (msgsnd(msq1,(void *)&msg,sizeof(msg.mtext),0)) { } printf("\t\t\t\ttwo: \t\tGREEN\n"); } } int main(int argc, char **args) { int pid; int msgkey =IPC_PRIVATE; struct msgbuf msg = { 1 }; if ((msq1 = msgget(msgkey, IPC_CREAT | 0666 ))==-1) { } if ((msq2 = msgget(msgkey, IPC_CREAT | 0666 ))==-1) { } if (msgsnd(msq1,(void *)&msg,sizeof(msg.mtext),0)) { } pid = fork(); switch (pid) { case 0 : // child one_process(); break; default: // parent two_process(); } }
gcc redgreen.que.c -o main && ./main one: RED one: GREEN two: RED two: GREEN one: RED one: GREEN two: RED two: GREEN one: RED one: GREEN two: RED two: GREEN one: RED one: GREEN two: RED two: GREEN one: RED one: GREEN two: RED two: GREEN one: RED one: GREEN two: RED
|
|
« Última modificación: 11 Abril 2019, 14:06 pm por dijsktra »
|
En línea
|
Si la depuración es el proceso de eliminar fallos en el software, entonces programar debe ser el proceso de ponerlos dentro. (Edsger Dijsktra)
|
|
|
|
|