Tutorial de implementación del bloqueo de lectura y escritura de Linux

  

Para lograr el bloqueo de lectura y escritura, primero debemos entender las características del bloqueo de lectura y escritura, además de que "los lectores pueden ser concurrentes, el escritor debe ser exclusivo", también debe considerar evitar que los escritores se mueran de hambre. Pregunta Después de una consideración exhaustiva, la implementación del bloqueo de lectura-escritura se puede resumir en los siguientes cuatro puntos: 1. Cuando se ha aplicado el bloqueo de escritura, el bloqueo de lectura no se puede aplicar (el bloqueo de escritura solo se puede bloquear una vez) 2. Cuando se ha aplicado la lectura Al bloquear, puede continuar aplicando el bloqueo de lectura, pero no puede aplicar el bloqueo de escritura. 3. Si tiene un camarero, no puede obtener el bloqueo de lectura (garantizar la prioridad del escritor). 4. Al desbloquear, si el escritor está esperando, el lector no puede ser despertado. Utilizamos mutexes y variables de condición para implementar bloqueos de lectura-escritura, que es la forma en que se implementan la mayoría de los sistemas. Además, este artículo principalmente quiere explicar la implementación del bloqueo de lectura-escritura, por lo que aquí solo se realizan las tres operaciones más básicas: solicitar el bloqueo de lectura, solicitar el bloqueo de escritura, desbloquear. No implementar inicialización, trylock, destruir bloqueos, etc. Typedef struct 2. {

3. pthread_mutex_t rw_mutex; //Proporciona acceso exclusivo a toda la estructura

4. pthread_cond_t rw_condreaders; //Se usa para notificar al subproceso que solicita el bloqueo de lectura

5. pthread_cond_t rw_condwriters; //se usa para notificar al subproceso que solicite el bloqueo de escritura

6. int rw_waitreaders; //esperando el número de subprocesos para solicitar el bloqueo de bloqueo

7. int rw_waitwriters; //El número de subprocesos que esperan para solicitar un bloqueo de escritura

8. int rw_refcount; //indica el estado del bloqueo de lectura-escritura, si es -1 indica que es un bloqueo de escritura

9.} pthread_rwlock_t; //0 indica que está disponible, mayor que 0 indica el número de bloqueos de lectura que se mantienen actualmente

10.

11.

12. int pthread_rwlock_rdlock (pthread_rwlock_t * rw) //Solicite un bloqueo de lectura 13. {

14. resultado int; //Valor de retorno (estado de error) 15.

16. pthread_mutex_lock (&​​amp; rw- > rw_mutex);

17. //Cuando el bloqueo de escritura está en uso, el bloqueo no se puede leer. Cuando el bloqueo está disponible pero hay un subproceso en espera de solicitar un bloqueo de escritura, el bloqueo no se puede leer. Esto se refleja en la "Prioridad del escritor". Rw- > rw_refcount < 0 | | Rw- > rw_waitwriters > 0)

19. {

20. rw- > rw_waitreaders ++;

21. result = pthread_cond_wait (&rw- > rw_condreaders , &rw- > rw_mutex); //Espere a que esté lista la condición de lectura

22.rw- > rw_waitreaders--;

23. if (result! = 0)

24. break;

25.}

26. if (result == 0)

27. rw- > rw_refcount ++; //Hay otro El nuevo hilo obtiene el bloqueo de lectura

28.

29. pthread_mutex_unlock (&​​amp; rw- > rw_mutex);

30. return (resultado);

31.}

32.

33.

34. int pthread_rwlock_wrlock (pthread_rwlock_t * rw) //Solicitar un bloqueo de escritura 35. {

36. int resultado; //valor de retorno (estado de error) 37.

38. pthread_mutex_lock (&​​amp; rw- > rw_mutex);

39. //aquí solo verifique si el bloqueo está Disponible en

40. while (rw- > rw_refcount! = 0)

41. {

42. rw- > rw_waitwriters ++;

43 Resultado = pthread_cond_wait (&rw- > rw_condwriters, &rw- > rw_mutex); //Espere a que aparezca la condición de escritura

44.rw- > rw_waitwriters--;

45. if (result! = 0)

46. break;

47 }

48. if (resultado == 0)

49. rw- > rw_refcount = -1; //El hilo adquiere el bloqueo de escritura

50. < Br>

51. pthread_mutex_unlock (&​​amp; rw- > rw_mutex);

52. return (resultado);

53.}

54.

55.

56.

57.

58. int pthread_rwlock_unlock (pthread_rwlock_t * rw) //desbloquear bloqueo (leer bloqueo, escribir bloqueo) 59. {

60. int resultado;

61.

62.

63. pthread_mutex_lock (&​​amp; rw- > rw_mutex);

64. if (rw- > refcount > 0)

65. rw- > refcount--;

66. else if (rw- > refcount == - 1)

67. rw- > refcount = 0;

68. else

69. printf (" rw- > refcount =% d \\ n " , rw- > refcount);

70. //Primero verifique si hay un escritor esperando, si hay alguno, primero active al escritor, esta es otra encarnación de "Prioridad de escritor" Br>

71. if (rw- > rw_waitwriters > 0)

72. {//No se puede escribir como si (rw- > rw_waitwriters > 0 &&rw- > refcount == 0 )

73. if (rw- > refcount == 0)

74. result = pthread_cond_signal (&rw- > rw_condwriters);

75.}

76. De lo contrario, si (rw- > rw_waitreaders > 0)

77. result = pthread_cond_signal (&rw- > rw_condreaders);

78.

79.

80. pthread_mutex_unlock (rw- > rw_mutex);

81. return resultado;

82.}

No se puede escribir como si (rw- > rw_waitwriters > 0 &&rw- > refcount == 0) La razón es que esto causará que el escritor se "pierda", es decir, debería garantizarse que cuando un escritor está esperando para solicitar un bloqueo, no puede permitir que el lector Solicite un bloqueo, de lo contrario, una secuencia de solicitud de lectura continua puede bloquear a un escritor en espera para siempre porque el lector puede bloquear varias veces. Escrito como si (rw- > rw_waitwriters > 0 &&rw- > refcount == 0), cuando la primera condición se cumple y la segunda no se cumple, es decir, el escritor está esperando y el lector está En el caso de un bloqueo, deberíamos simplemente liberar un bloqueo de lectura y no hacer nada más, pero aquí ejecutaremos el otro si, haciendo que el lector se active y permita que el lector obtenga el bloqueo.

Copyright © Conocimiento de Windows All Rights Reserved