elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Arreglado, de nuevo, el registro del warzone (wargame) de EHN


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Problema con buzones
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Problema con buzones  (Leído 2,027 veces)
snowspring

Desconectado Desconectado

Mensajes: 12


Ver Perfil
Problema con buzones
« 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:

Código
  1. int buzon = atoi(p_memC+334); //el buzon esta correctamente inicializado y guardado en memoria compartida
  2.        int envio, recibo;
  3.  
  4.        struct tipo_mensaje
  5. {
  6.        long tipo;
  7.        char mensaje[20];
  8. }mensaje;
  9.  
  10.        while(1){
  11.  
  12.        if(*(p_memC+274) == VERDE)      //aqui se comprueba el estado del semaforo horizontal, el estado lo actualiza automaticamente luz_sem
  13.        {
  14.        luz_sem(HORIZONTAL, ROJO);
  15.        strcpy(mensaje.mensaje, "HORIZ ROJO");
  16.        mensaje.tipo = HORIZONTALROJO;
  17.        if((envio = msgsnd(buzon, &mensaje, sizeof(struct tipo_mensaje)-sizeof(long), MSG_NOERROR))==-1)
  18.        {
  19.                perror("msgnd");
  20.                raise(SIGINT);
  21.        }
  22.        }else if(*(p_memC+274) == ROJO){
  23.                mensaje.tipo=VERTICALROJO;
  24.                if((recibo=msgrcv(buzon, &mensaje, sizeof(struct tipo_mensaje)-sizeof(long), mensaje.tipo, MSG_NOERROR))==-1)
  25.                {
  26.                        perror("msgrcv");
  27.                        raise(SIGINT);
  28.                }
  29.  
  30.        luz_sem(HORIZONTAL, VERDE);        //esta es una funcion que esta comprobada que funciona correctamente para cambiar el semaforo de color
  31.  
  32.        }else if(*(p_memC+275) == VERDE){      //aqui se comprueba el estado del semaforo horizontal, el estado lo actualiza automaticamente luz_sem
  33.         luz_sem(VERTICAL, ROJO);
  34.         strcpy(mensaje.mensaje, "VERTICAL ROJO");
  35.         mensaje.tipo = VERTICALROJO;
  36.         if((envio = msgsnd(buzon, &mensaje, sizeof(struct tipo_mensaje)-sizeof(long), MSG_NOERROR))==-1)
  37.         {
  38.                perror("msgnd");
  39.                raise(SIGINT);
  40.         }
  41.        }else if(*(p_memC+275) == ROJO){
  42.                mensaje.tipo=HORIZONTALROJO;
  43.                if((recibo=msgrcv(buzon, &mensaje, sizeof(struct tipo_mensaje)-sizeof(long), mensaje.tipo, MSG_NOERROR))==-1)
  44.                {
  45.                        perror("msgrcv");
  46.                        raise(SIGINT);
  47.                }
  48.         luz_sem(VERTICAL, VERDE);
  49.        }
  50. }

Muchas gracias!


En línea

CalgaryCorpus


Desconectado Desconectado

Mensajes: 323


Ver Perfil WWW
Re: Problema con buzones
« Respuesta #1 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.



En línea

Aqui mi perfil en LinkedIn, invitame un cafe aqui
dijsktra

Desconectado Desconectado

Mensajes: 110


Mr Edsger Dijsktra (Tribute to)


Ver Perfil
Re: Problema con buzones
« Respuesta #2 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....

Código
  1. /*
  2.   Syncrhonized red-green semaphores
  3.  
  4.   using semaphores...
  5.  
  6.   Safety Invariant:
  7.      0 <= one_sem + two_sem <= 1
  8.  
  9. */
  10.  
  11. #include <pthread.h>
  12. #include <semaphore.h>
  13.  
  14.  
  15. #include <stdlib.h>  // exit
  16. #include <stdio.h>  // print
  17. #include <unistd.h> // sleep
  18. sem_t one_sem;
  19. sem_t two_sem;
  20.  
  21.  
  22. void* one_thread(void *arg)
  23. {
  24.  for( ; 1 ; )
  25.    {
  26.      if (sem_wait(&one_sem))
  27. {
  28.  perror("sem_wait");
  29.  exit(1);
  30. }
  31.      printf("one: \t\tRED\n");
  32.      sleep(2);
  33.      if (sem_post(&two_sem))
  34. {
  35.  perror("sem_post");
  36.  exit(1);
  37. }
  38.      printf("one: \t\tGREEN\n");
  39.    }
  40. }
  41.  
  42.  
  43. void* two_thread(void *arg)
  44. {
  45.  for( ; 1 ; )
  46.    {
  47.      if (sem_wait(&two_sem))
  48. {
  49.  perror("sem_wait");
  50.  exit(1);
  51. }
  52.      printf("\t\t\t\ttwo: \t\tRED\n");
  53.      sleep(2);
  54.      if (sem_post(&one_sem))
  55. {
  56.  perror("sem_post");
  57.  exit(1);
  58. }
  59.      printf("\t\t\t\ttwo: \t\tGREEN\n");
  60.    }
  61. }
  62.  
  63.  
  64. int main(int argc, char **args)
  65. {
  66.  pthread_t one,two;
  67.  
  68.  sem_init(&one_sem,0,1);
  69.  sem_init(&two_sem,0,0);
  70.  if (pthread_create(&one, NULL, one_thread, NULL))
  71.    {
  72.      perror("pthread_create");
  73.      exit(1);
  74.    }
  75.  if (pthread_create(&two, NULL, two_thread, NULL))
  76.    {
  77.      perror("pthread_create");
  78.      exit(1);
  79.    }
  80.  
  81.  if (!pthread_join(one,NULL))
  82.    {
  83.      perror("pthread_join");
  84.      exit(1);
  85.    }
  86.  
  87.    if (!pthread_join(two,NULL))
  88.    {
  89.      perror("pthread_join");
  90.      exit(1);
  91.    }
  92.  
  93. }
  94.  


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.)
Código:
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 Desconectado

Mensajes: 110


Mr Edsger Dijsktra (Tribute to)


Ver Perfil
Re: Problema con buzones [con queues]
« Respuesta #3 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"...



Código
  1. /*
  2.   Syncrhonized red-green semaphores
  3.  
  4.   using queues
  5.  
  6.   a queue can act as a distributed semaphore
  7. */
  8. #include <sys/types.h>
  9. #include <sys/ipc.h>
  10. #include <sys/msg.h>
  11.  
  12. #include <sys/stat.h>
  13. #include <fcntl.h>
  14.  
  15.  
  16.  
  17. #include <stdlib.h>  // exit
  18. #include <stdio.h>  // print
  19. #include <unistd.h> // sleep
  20.  
  21. int msq1;
  22. int msq2; // queue descriptors...
  23.  
  24.  
  25. typedef struct msgbuf {
  26.  long mtype;       /* message type, must be > 0 */
  27.  char mtext[0];    /* message data */
  28. } msg;
  29.  
  30.  
  31. void one_process()
  32. {
  33.  struct msgbuf msg = {  1 };
  34.  for( ; 1 ; )
  35.    {
  36.      if (msgrcv(msq1,(void *)&msg,sizeof(msg.mtext),0,0)==-1)
  37. {
  38.  perror("msgrcv");
  39.  exit(EXIT_FAILURE);
  40. }
  41.      printf("one: \t\tRED\n");
  42.      sleep(2);
  43.      if (msgsnd(msq2,(void *)&msg,sizeof(msg.mtext),0))
  44. {
  45.  perror("msgsnd");
  46.  exit(1);
  47. }
  48.      printf("one: \t\tGREEN\n");
  49.    }
  50. }
  51.  
  52.  
  53. void two_process()
  54. {
  55.  struct msgbuf msg = { 1 };
  56.  for( ; 1 ; )
  57.    {
  58.      if (msgrcv(msq2,(void *)&msg,sizeof(msg.mtext),0,0)==-1)
  59. {
  60.  perror("msgrcv");
  61.  exit(EXIT_FAILURE);
  62. }      printf("\t\t\t\ttwo: \t\tRED\n");
  63.      sleep(2);
  64.      if (msgsnd(msq1,(void *)&msg,sizeof(msg.mtext),0))
  65. {
  66.  perror("msgsnd");
  67.  exit(1);
  68. }
  69.      printf("\t\t\t\ttwo: \t\tGREEN\n");
  70.    }
  71. }
  72.  
  73.  
  74. int main(int argc, char **args)
  75. {
  76.  int pid;
  77.  int msgkey =IPC_PRIVATE;
  78.  struct msgbuf msg = { 1 };
  79.  
  80.  if ((msq1 = msgget(msgkey, IPC_CREAT | 0666 ))==-1)
  81.    {
  82.      perror("msgget");
  83.      exit(EXIT_FAILURE);
  84.    }
  85.  
  86.  if ((msq2 = msgget(msgkey, IPC_CREAT | 0666 ))==-1)
  87.    {
  88.      perror("msgget");
  89.      exit(EXIT_FAILURE);
  90.    }
  91.  
  92.  if (msgsnd(msq1,(void *)&msg,sizeof(msg.mtext),0))
  93.    {
  94.      perror("msgsnd");
  95.      exit(1);
  96.    }  
  97.  pid = fork();
  98.  switch (pid)
  99.    {
  100.    case 0 : // child
  101.      one_process();
  102.      break;
  103.    default: // parent
  104.      two_process();
  105.    }
  106.  
  107. }
  108.  








Código:
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)
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Problema al mover Bound Import Problema para copiar y pegar
Análisis y Diseño de Malware
kisk 2 3,777 Último mensaje 4 Abril 2017, 03:13 am
por kisk
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines