Título: Problema con buzones
Publicado por: snowspring en 4 Abril 2019, 18:47 pm
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!
Título: Re: Problema con buzones
Publicado por: CalgaryCorpus en 5 Abril 2019, 16:11 pm
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.
Título: Re: Problema con buzones
Publicado por: dijsktra en 8 Abril 2019, 15:14 pm
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 ;D 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
Título: Re: Problema con buzones [con queues]
Publicado por: dijsktra en 10 Abril 2019, 15:44 pm
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
|