Semaforos en c

Iniciado por prosebas, 16 Mayo 2021, 02:03 AM

0 Miembros y 1 Visitante están viendo este tema.

prosebas

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.


#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>
sem_t semaphore;
void *routine(void *routine)
{
     for (int i = 0; i < 3; i++)
     {
          sem_wait(&semaphore);
          printf("%s\n", (char *)routine);
          sleep(1);
          sem_post(&semaphore);
     }
}
int main(void)
{
     sem_init(&semaphore, 0, 1);
     pthread_t thread[3];
     pthread_create(&thread[0], NULL, routine, "A");
     pthread_create(&thread[1], NULL, routine, "B");
     pthread_create(&thread[2], NULL, routine, "C");
     for (int i = 0; i < 3; i++)
     {
          pthread_join(thread[i], NULL);
          sleep(1);
     }
}


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

RayR

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í:


sem_post(&semaphore[(n + 1) % 3 ]);


y para imprimir la letra correcta, algo como:


putchar('A' + n);


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

dijsktra

Cita de: RayR en 16 Mayo 2021, 19:57 PM
... 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.


#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <semaphore.h>
#include <unistd.h> // sleep thread.
#include <string.h> // memcopy

static const char values[3]={'A','B','C'};
static sem_t semaphore[3];
static pthread_t thread[3];

static void *routine(void *arg);

int main(int argc, char *args[])
{
    for (int i = 0; i < 3; i++)
if (sem_init(&(semaphore[i]), 0, (i==0)?1:0))
    {
perror("sem_init");
exit(-1);
    }
    for (int i = 0; i < 3; i++)
{
    int *local_idx;
    if ((local_idx= (int *)malloc(sizeof(int)))==NULL)
{
    perror("malloc");
    exit(-1);
}
    *local_idx=i;
    if  (pthread_create(&thread[i], NULL, routine, local_idx))
    {
        perror("pthread_create");
        exit(-1);
    }
}
    for (int i = 0; i < 3; i++)
      if (pthread_join(thread[i], NULL))
{
  perror("pthread_join");
  exit(-1);
}
}

static void *routine(void *arg)
{
    int local_id;
    memcpy(&local_id,arg,sizeof(int));
    free(arg);
    for( ; 1 ; )
{
    if (sem_wait(&semaphore[local_id]))
{
    perror("sem_wait");
    exit(-1);
}
    printf("%c",values[local_id]);
    //sleep(1);
    if (sem_post(&semaphore[(local_id+1)%3]))
{
    perror("sem_post");
    exit(-1);
}
}
}



Ejemplo de salida

ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC...
Si la depuración es el proceso de eliminar fallos en el software, entonces programar debe ser el proceso de ponerlos dentro. (Edsger Dijsktra)

RayR

Cita de: dijsktra en 25 Junio 2021, 10:22 AM
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).

dijsktra

Cita de: RayR en 25 Junio 2021, 15:27 PM
¿¿¿??? Pues eso es lo que puse en mi mensaje:


Tienes Razon, RayR... Acabe cansado de implementarlo y no lei del todo tu respuesta.
Si la depuración es el proceso de eliminar fallos en el software, entonces programar debe ser el proceso de ponerlos dentro. (Edsger Dijsktra)

Eternal Idol

Cita de: dijsktra en 25 Junio 2021, 17:48 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.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón