当前位置:网站首页>Verrouillage de lecture et d'écriture pour la synchronisation des fils

Verrouillage de lecture et d'écriture pour la synchronisation des fils

2022-06-26 03:58:00 Studywinter

Comme mutex,Mais les serrures lecture - écriture permettent un parallélisme plus élevé.Ses caractéristiques sont les suivantes:: Exclusivité de l'écriture,Lire le partage.

1 Lire et écrire l'état de la serrure

Un accent particulier est mis sur: Il n'y a qu'une seule serrure pour lire et écrire, Mais il a deux états:

1 Verrouillage en mode lecture (Lisez la serrure.);
2 Verrouillage en mode écriture (Écris la serrure.) .

2 Caractéristiques de la serrure lecture - écriture

1 Lire et écrire la serrure est“Mode écriture plus verrouillage”Heure, Avant de déverrouiller,Tous les fils qui verrouillent cette serrure seront bloqués;
2 Lire et écrire la serrure est“Mode lecture plus verrouillage”Heure, Si le thread est verrouillé en mode lecture, il réussira;Si le thread est verrouillé en mode écriture, il sera bloqué;
3 Lire et écrire la serrure est“Mode lecture plus verrouillage”Heure, Il y a des fils qui essaient de verrouiller en mode écriture,Il y a aussi des fils qui essaient de verrouiller en mode lecture.Alors le verrouillage lecture - écriture bloquera les demandes de verrouillage de mode lecture subséquentes.Priorité pour satisfaire au verrouillage du mode d'écriture. Lisez la serrure.、Bloc parallèle write Lock, Priorité d'écriture élevée .

Les serrures de lecture et d'écriture sont également connues sous le nom de partage-Serrure exclusive.Lorsque la serrure lecture - écriture est verrouillée en mode lecture,Il est verrouillé en mode partagé;Quand il est verrouillé en mode écriture,Il est verrouillé en mode exclusif. Exclusivité de l'écriture、Lire le partage.Les serrures lecture - écriture sont idéales pour les situations où le nombre de lectures sur les structures de données est beaucoup plus élevé que celui des lectures.

Fonction principale

pthread_rwlock_t rwlock;
pthread_rwlock_init(&rwlock, NULL);
pthread_rwlock_rdlock(&rwlock);       // try
pthread_rwlock_wrlock(&rwlock);       // try
pthread_rwlock_unlock(&rwlock);
pthread_rwlock_destroy(&rwlock);

Toutes les fonctions ci - dessus sont retournées avec succès 0,Échec renvoie le numéro d'erreur.

(1)pthread_rwlock_init Fonctions

Initialiser une serrure de lecture - écriture

pthread_rwlock_t rwlock;

// Méthodes1
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,
                        const pthread_rwlockattr_t *restrict attr);
// Voir 2: attr  Table Read Write Lock Properties , Les propriétés par défaut sont généralement utilisées , Passe NULL C'est tout.
// Méthodes2
rwlock = PTHREAD_RWLOCK_INITIALIZER;

(2)pthread_rwlock_destroy Fonctions

Détruire une serrure de lecture - écriture

int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

(3)pthread_rwlock_rdlock Fonctions

Demande de verrouillage lecture - écriture en mode lecture .(Souvent abrégé en:Demande de lecture de la serrure)

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);

(4)pthread_rwlock_wrlock Fonctions

Demande de verrouillage lecture - écriture en écriture .(Souvent abrégé en:Demande de verrouillage d'écriture)

int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);

(5)pthread_rwlock_unlock Fonctions

Déverrouiller

int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

(6)pthread_rwlock_tryrdlock Fonctions

Demande de verrouillage lecture - écriture sans blocage ( Demande de lecture non bloquante )

int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);

(7)pthread_rwlock_trywrlockFonctions

Demande de verrouillage lecture - écriture non bloquée ( Demande d'écriture non bloquante )

int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);

3  Deux types d'impasses

Est un phénomène causé par une utilisation inappropriée des serrures :

1. Répéter sur une serrure lock.
2. Deux fils,Chacun avec une serrure, Demande une autre main. .

4  Cas de verrouillage lecture - écriture  

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>

//  Ressources partagées à l'échelle mondiale 
int counter;

// Global Read Write Lock,Initialisation
pthread_rwlock_t rwlock;

// rwlock = PTHREAD_RWLOCK_INITIALIZER;

// Mission:3 Les Threads écrivent la même ressource en même temps ,5 Les Threads lisent la même ressource en même temps 

// Écris.
void *do_write(void *arg)
{
    int t = 0;
    int i = (int)arg;
    int res = 0;

    while (1)
    {
        // Verrouillage,Write Lock exclusive
        res = pthread_rwlock_wrlock(&rwlock);
        if (res != 0)
        {
            fprintf(stderr, "pthread_rwlock_wrlock error:%s\n", strerror(res));
            exit(1);
        }
        t = counter;
        usleep(10000);
        //  Modifier est écrire 
        printf("------write:%d, %lu, counter = %d, ++counter = %d\n", i, pthread_self(), t, ++counter);

        // Déverrouiller
        res = pthread_rwlock_unlock(&rwlock);
        if (res != 0)
        {
            fprintf(stderr, "pthread_rwlock_unlock error:%s\n", strerror(res));
            exit(1);
        }
        usleep(10000);
    }
    return NULL;
}

// Lire
void *do_read(void *arg)
{
    int res = 0;
    int i = (int)arg;
    while (1) {
         // Verrouillage,Lire le partage
        res = pthread_rwlock_rdlock(&rwlock);
        if (res != 0)
        {
            fprintf(stderr, "pthread_rwlock_rdlock error:%s\n", strerror(res));
            exit(1);
        }
        usleep(10000);
        //  Modifier est écrire 
        printf("==========================================read:%d, %lu, counter = %d\n", i, pthread_self(), counter);

        // Déverrouiller
        res = pthread_rwlock_unlock(&rwlock);
        if (res != 0)
        {
            fprintf(stderr, "pthread_rwlock_unlock error:%s\n", strerror(res));
            exit(1);
        }
        usleep(10000);
    }
    return NULL;
}

int main(int argc, char **argv)
{
    int i;
    // 8Threads
    pthread_t tid[8];

    // Initialisation des serrures de lecture et d'écriture
    int res = pthread_rwlock_init(&rwlock, NULL);
    if (res != 0)
    {
        fprintf(stderr, "pthread_rwlock_init error:%s\n", strerror(res));
        exit(1);
    }

    // Initialiser le thread
    // Écrire des fils
    for (i = 0; i < 3; i++)
    {
        res = pthread_create(&tid[i], NULL, do_write, (void *)i);
        if (res != 0)
        {
            fprintf(stderr, "pthread_create write error:%s\n", strerror(res));
            exit(1);
        }
    }

    // Lire le fil
    for (i = 3; i < 8; i++)
    {
        res = pthread_create(&tid[i], NULL, do_read, (void *)i);
        if (res != 0)
        {
            fprintf(stderr, "pthread_create read error:%s\n", strerror(res));
            exit(1);
        }
    }

    // Recycler les sous - fils
    for (i = 0; i < 8; i++)
    {
        res = pthread_join(tid[i], NULL);
        if (res != 0)
        {
            fprintf(stderr, "pthread_join error:%s\n", strerror(res));
            exit(1);
        }
    }

    // Détruire les serrures de lecture et d'écriture
    res = pthread_rwlock_destroy(&rwlock);
    if (res != 0)
    {
        fprintf(stderr, "pthread_join error:%s\n", strerror(res));
        exit(1);
    }

    return 0;
}

Mise en œuvre

Sortie rapide du programme , Prenez une photo. ,Comme indiqué ci - dessus.
En raison du partage de lecture ,Exclusivité de l'écriture.Priorité d'écriture élevée.Devant.5- Oui.read Ça doit être avant. writeArrivée,Non.write La serrure sera saisie pour l'écriture en premier .

原网站

版权声明
本文为[Studywinter]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/177/202206260356298876.html