Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: prosebas en 16 Mayo 2021, 02:03 am



Título: Semaforos en c
Publicado por: prosebas en 16 Mayo 2021, 02:03 am
Hola buenas noches a todos, estoy empezando en el tema de sincronización de procesos a través de semaforos basicamente lo que me piden hacer es que apartir de tres procesos A,B y C tenga como salida ABC ABC ABC utilizando semaforos.

Código
  1. #include <stdlib.h>
  2. #include <pthread.h>
  3. #include <stdio.h>
  4. #include <unistd.h>
  5. #include <semaphore.h>
  6. sem_t semaphore;
  7. void *routine(void *routine)
  8. {
  9.     for (int i = 0; i < 3; i++)
  10.     {
  11.          sem_wait(&semaphore);
  12.          printf("%s\n", (char *)routine);
  13.          sleep(1);
  14.          sem_post(&semaphore);
  15.     }
  16. }
  17. int main(void)
  18. {
  19.     sem_init(&semaphore, 0, 1);
  20.     pthread_t thread[3];
  21.     pthread_create(&thread[0], NULL, routine, "A");
  22.     pthread_create(&thread[1], NULL, routine, "B");
  23.     pthread_create(&thread[2], NULL, routine, "C");
  24.     for (int i = 0; i < 3; i++)
  25.     {
  26.          pthread_join(thread[i], NULL);
  27.          sleep(1);
  28.     }
  29. }
  30.  

Esa es la implementación que llevo hasta el momento, sin embargo,la salida me es erronea

Esta es mi salida:
AAA BBB CCC

Les agredezco si me pueden ayudar  ;D


Título: Re: Semaforos en c
Publicado por: RayR en 16 Mayo 2021, 19:57 pm
Es que así como lo hiciste no hay garantía de ningún orden específico. Y es que ni siquiera es seguro que los hilos se ejecuten en el orden de creación.

No sé si te dieron indicaciones específicas para el ejercicio, pero lo podrías resolver de forma sencilla con tres semáforos. Creas un array de ellos y el primero lo inicializas a 1, y los otros a 0. A cada hilo le podrías enviar como parámetro entero su número de índice. Cada hilo "n" espera por el semáforo n, e incrementa (sem_post) el semáforo n + 1, a excepción del último (2), que incrementará el primero (0). Esto lo podrías hacer así:

Código
  1. sem_post(&semaphore[(n + 1) % 3 ]);

y para imprimir la letra correcta, algo como:

Código
  1. putchar('A' + n);

También deberías llamar a sem_destroy para destruir los semáforos al final.


Título: Re: Semaforos en c
Publicado por: dijsktra en 25 Junio 2021, 10:22 am
... A cada hilo le podrías enviar como parámetro entero su número de índice. Cada hilo "n" espera por el semáforo n, e incrementa (sem_post) el semáforo n + 1, a excepción del último (2), que incrementará el primero (0).
El planteamiento es correcto. Pero es importante resaltar el valor inicial de los semáforos. Todos a 0, menos el primero, a 1.

Aqui va una implementación.

Código
  1. #include <pthread.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <semaphore.h>
  5. #include <unistd.h> // sleep thread.
  6. #include <string.h> // memcopy
  7.  
  8. static const char values[3]={'A','B','C'};
  9. static sem_t semaphore[3];
  10. static pthread_t thread[3];
  11.  
  12. static void *routine(void *arg);
  13.  
  14. int main(int argc, char *args[])
  15. {
  16.    for (int i = 0; i < 3; i++)
  17. if (sem_init(&(semaphore[i]), 0, (i==0)?1:0))
  18.    {
  19. perror("sem_init");
  20. exit(-1);
  21.    }
  22.    for (int i = 0; i < 3; i++)
  23. {
  24.    int *local_idx;
  25.    if ((local_idx= (int *)malloc(sizeof(int)))==NULL)
  26. {
  27.    perror("malloc");
  28.    exit(-1);
  29. }
  30.    *local_idx=i;
  31.    if  (pthread_create(&thread[i], NULL, routine, local_idx))
  32.     {
  33.        perror("pthread_create");
  34.        exit(-1);
  35.     }
  36. }
  37.    for (int i = 0; i < 3; i++)
  38.      if (pthread_join(thread[i], NULL))
  39. {
  40.  perror("pthread_join");
  41.  exit(-1);
  42. }
  43. }
  44.  
  45. static void *routine(void *arg)
  46. {
  47.    int local_id;
  48.    memcpy(&local_id,arg,sizeof(int));
  49.    free(arg);
  50.    for( ; 1 ; )
  51. {
  52.    if (sem_wait(&semaphore[local_id]))
  53. {
  54.    perror("sem_wait");
  55.    exit(-1);
  56. }
  57.    printf("%c",values[local_id]);
  58.    //sleep(1);
  59.    if (sem_post(&semaphore[(local_id+1)%3]))
  60. {
  61.    perror("sem_post");
  62.    exit(-1);
  63. }
  64. }
  65. }
  66.  
  67.  

Ejemplo de salida
Código:
ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC...


Título: Re: Semaforos en c
Publicado por: RayR en 25 Junio 2021, 15:27 pm
El planteamiento es correcto. Pero es importante resaltar el valor inicial de los semáforos. Todos a 0, menos el primero, a 1.

¿¿¿??? Pues eso es lo que puse en mi mensaje:

Cita de: RayR
el primero lo inicializas a 1, y los otros a 0. A cada hilo le podrías enviar como parámetro entero su número de índice. Cada hilo "n" espera por el semáforo n, e incrementa (sem_post) el semáforo n + 1, a excepción del último (2), que incrementará el primero (0).


Título: Re: Semaforos en c
Publicado por: dijsktra en 25 Junio 2021, 17:48 pm
¿¿¿??? Pues eso es lo que puse en mi mensaje:


Tienes Razon, RayR... Acabe cansado de implementarlo y no lei del todo tu respuesta.


Título: Re: Semaforos en c
Publicado por: Eternal Idol en 25 Junio 2021, 19:26 pm
Tienes Razon, RayR... Acabe cansado de implementarlo y no lei del todo tu respuesta.

Bueno, trata de recordarlo para la proxima y no hacer tareas ajenas.