Publi

Creando un mutex con semáforos entre procesos hijos en C [fork()]

Hemos estado viendo cómo compartir variables entre procesos hijos, y dejamos un poco en el tintero la implementación de mutex en ese caso, esta vez, para implementar el mutex vamos a utilizar semáforos. Estos semáforos también tienen que ser variables compartidas para funcionar correctamente.

Los semáforos tendrá un funcionamiento peculiar. En principio, pensemos en ellos con los valores 1 y 0. Por tanto, si el semáforo vale 1, el semáforo está abierto y lo haremos 0, pero si vale 0, nos esperaremos hasta que valga 1 (al contrario que un while (semaforo==0); utilizando semáforos, será el sistema operativo el que active nuestro proceso cuando el semáforo vale 1 por lo que podemos utilizar los recursos del sistema para otra cosa mientras).
Aunque podemos ir más allá, el valor del semáforo (numérico) podrá ser cualquiera, pero siempre que éste sea positivo, el proceso no se bloqueará, pero sí se decrementará el valor; aunque si el valor es negativo, o cero, el valor se decrementa, pero el proceso se queda esperando un valor positivo.
Al fin y al cabo un mutex es un semáforo que sólo vale 1 y 0 (aunque situado estratégicamente para proteger una sección crítica).

Para utilizar los semáforos tenemos que tener en cuenta tres funciones básicas (hay algunas más):

  • sem_init(semaforo, pshared, value): Inicializamos el semáforo, y le damos el valor value. pshared deberá ser 0 si queremos el semáforo entre threads, u otro valor si queremos el semáforo compartido entre procesos. En este caso, será 1
  • sem_post(semaforo): Incrementa el semáforo, es lo que utilizamos cuando se libera el recurso
  • sem_wait(semaforo): Decrementa el semáforo, y si su valor es menor que cero, bloquea el proceso hasta tener un valor mayor o igual a cero. Lo usamos para comprobar si el recurso está ocupado.

En el siguiente ejemplo incrementaremos un número, aunque para complicarlo un poco, este número vendrá dado por una cadena de caracteres, cada incremento debe hacerlo un proceso hijo diferente por lo que tienen que estar todos perfectamente sincronizados para hacerlo bien. El valor final de x debe ser 20. Por otro lado, se han introducido esperas aleatorias para simular un proceso pesado que tarda un tiempo variable, y así provocar la condición de carrera.

Podemos modificar el valor de la constante SEMAPHORES De 1 a 0 para ver cómo se comporta el código en cada caso.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <sys/mman.h>
#include <semaphore.h>
#include <string.h>

#define SEMAPHORES 1

int main()
{
  char *x = mmap(NULL, sizeof(char)*10, PROT_READ | PROT_WRITE,
               MAP_SHARED | MAP_ANONYMOUS, -1, 0);
  strcpy(x, "0");

  int i;
  int child;
  sem_t *semaforo = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE,
             MAP_SHARED | MAP_ANONYMOUS, -1, 0);
  int temp;
  sem_init (semaforo, 1, 1);
  for (i=0; i<10; ++i)
    {
      child = fork();
      if (child==0)
    {
      usleep(rand()%20000);

      if (SEMAPHORES)
        sem_wait(semaforo);
      printf("[%d] Trying to access the resource\n", getpid());
      temp=atoi(x);
      printf("[%d] Using the resource\n", getpid());
      temp++;
      sprintf(x, "%d", temp);

      if (SEMAPHORES)
        sem_post(semaforo);
      printf("[%d] Just used the resource\n", getpid());
      usleep(rand()%20000);

      if (SEMAPHORES)
        sem_wait(semaforo);
      printf("[%d] Trying to access the resource\n", getpid());
      temp=atoi(x);
      printf("[%d] Using the resource\n", getpid());
      temp++;
      sprintf(x, "%d", temp);

      if (SEMAPHORES)
        sem_post(semaforo);
      printf("[%d] Just used the resource\n", getpid());
      printf("[%d] EXITING\n", getpid());
      exit(1);
    }
    }

   while (wait(NULL)>=0);

  printf("x is: %s\n", x);
  munmap(x, sizeof(int));
  munmap(semaforo, sizeof(sem_t));

  return 0;
}

Cada vez que un proceso vaya a acceder a nuestra sección crítica, lo pondrá en pantalla junto con su pid, por lo que podemos ver claramente si un proceso está utilizando el recurso y otro proceso también entra a utilizarlo. Finalmente se dirá el valor de x, que debe ser 20 y que en el ejemplo sin semáforos no siempre vale 20. (Puede que alguna vez lo haga bien, pero será casualidad.

Nota: Debemos compilar con soporte para pthread:

$ gcc -o example example.c -lpthread

Foto: Paul Albertella (Flickr) CC-by

También podría interesarte....

There are 33 comments left Ir a comentario

  1. Pingback: BlogESfera.com /

  2. Mike Rooney /
    Usando Google Chrome Google Chrome 117.0.0.0 en Windows Windows NT

    This is such awesome content i got to read after lot of time. Its so interesting as well as informative. I am sure everyone who read it got a lot to learn from it.Miles Morales Hooded Bomber Jacket

  3. Andrew Mark /
    Usando Google Chrome Google Chrome 117.0.0.0 en Windows Windows NT

    This is excellent article, thank you for the share! This is what I am looking for, hope in future you will continue sharing such an superb work.
    Coat Blade Runner 2049

  4. Willis Owen /
    Usando Google Chrome Google Chrome 118.0.0.0 en Windows Windows NT

    This post you’re sharing is excellent. I really like and value what you’ve done. I really read your post, and I appreciate you providing the very useful points you raised. connections game

  5. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    Actually, it’s pretty good to see! Tiler Adelaide

  6. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    Thanks for sharing! Tiler Adelaide

  7. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    Thanks for letting us know! Tiler Wollongong

  8. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    Excellent post! Concreters in Wollongong

  9. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    Thanks for sharing this to public! Adelaide Landscaping

  10. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    I visited Your blog and got a massive number of informative articles. I read many articles carefully and got the information that I had been looking for for a long time. Hope you will write such a helpful article in future. Thanks for writing.Tilers in Hobart

  11. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    Very useful and informative post! Tiling Townsville

  12. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    Very informative post! tiler melbourne

  13. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    To be honest, I generally don’t read. But, this article caught my attention.digital marketing adelaide

  14. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    I am really impressed with your writing style. Keep it up! Landscapers Canberra

  15. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    Many thanks for sharing this! Adelaide Coolroom Hire

  16. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    Thanks for sharing! Sliding Doors Adelaide

  17. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    It’s so kind of you! Solar Panels Adelaide

  18. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    Many many thanks to you! Cleaning Services Adelaide

  19. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    What a great piece of article! seo adelaide

  20. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    Very informative content. Thanks. tow truck wollongong

  21. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    Please keep up the good work! drum lessons adelaide

  22. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    Thanks for letting us know. Tiler Adelaide

  23. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    I thik this is very helpfull post Canberra landscapers

  24. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    Great Post! I learned a lot from this, Thank you! Canberra landscapers

  25. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    Really nice article and helpful me Canberra landscapers

  26. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    Nice article, waiting for your another Canberra landscapers

  27. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    This is awesome! Nice share. Best Cymbals on a Budget

  28. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    Such a great post! Landscaping Henley Beach

  29. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    Thats what I was looking for! adelaide air conditioning

  30. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    Good to know about this! tilers wollongong Warilla

  31. James Song /
    Usando Google Chrome Google Chrome 119.0.0.0 en Windows Windows NT

    This is really very nice blog and so informative Sydney Tiler

  32. Melba Frami /
    Usando Google Chrome Google Chrome 121.0.0.0 en Windows Windows NT

    Say goodbye to the old, boring WhatsApp user interface and its features, and say hello to WhatsApp Plus Update APK (Anti-Ban). A new futuristic WhatsApp MOD with exciting features like sharing larger files, freezing last seen etc and beautiful and improved UI.

  33. Kwabena /
    Usando Google Chrome Google Chrome 122.0.0.0 en Windows Windows NT

    Heya i’m for the primary time here. I came across this board and I in finding It truly useful & it helped me out much. I’m hoping to provide something again and help others such as you aided me.

    Pinjaman

Leave a Reply