verrou de lecture/écriture dans pthread

Je suis en train d'apprendre pthread et suis tombé sur un verrou en lecture /écriture. Le scénario est très simple, une variable globale partagée par tous les threads, le lecteur garde l'impression de la valeur actuelle de cette même variable globale, tandis que l'écrivain sera mise à jour de la même variable. Je peux réaliser cette synchronisation à l'aide de deux mutex (pthread_mutex_t), mais je veux utiliser "un" lecteur-écrivain de verrouillage pour parvenir à ce même résultat. Cependant, avec un lecteur-écrivain de verrouillage, comme on peut le voir ici(sortie du programme, ci-dessous), le lecteur ne voit que la première valeur de x et ne voit toutes les mises à jour de la variable globale. S'il vous plaît jeter un peu de lumière ici.

Code:

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <pthread.h>
#include <poll.h>
#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
int x = 0;
pthread_rwlock_t lock_rw = PTHREAD_RWLOCK_INITIALIZER;
void *reader_thread(void *arg)
{
int i;
int newx, oldx;
newx = oldx = -1;
pthread_rwlock_t *p = (pthread_rwlock_t *)arg;
if (pthread_rwlock_rdlock(p) != 0) {
perror("reader_thread: pthread_rwlock_rdlock error");
exit(__LINE__);
}
for (i = 0; i < 100; i++) {
newx = ACCESS_ONCE(x);
if (newx != oldx) {
printf("reader_lock: x: %d\n",x);
}
oldx = newx;
poll(NULL, 0, 1);
}
if (pthread_rwlock_unlock(p) != 0) {
perror("reader thread: pthred_rwlock_unlock error");
exit(__LINE__);
}
return NULL;
}
void *writer_thread(void *arg)
{
int i;
pthread_rwlock_t *p = (pthread_rwlock_t *)arg;
if (pthread_rwlock_wrlock(p) != 0) {
perror("writer thread: pthread_rwlock_wrlock error");
exit(__LINE__);
}
for (i = 0; i < 3; i++) {
ACCESS_ONCE(x)++;
poll(NULL, 0, 5);
}
if (pthread_rwlock_unlock(p) != 0) {
perror("writer thread: pthread_rwlock_unlock error");
exit(__LINE__);
}
return NULL;
}
int main(void)
{
pthread_t tid1, tid2;
void *vp;
if (pthread_create(&tid1, NULL, reader_thread, &lock_rw) != 0) {
perror("pthread_create error");
exit (__LINE__);
}
if (pthread_create(&tid2, NULL, writer_thread, &lock_rw) != 0) {
perror("pthread_create error");
exit (__LINE__);
}
//wait for the thread to complete
if (pthread_join(tid1, &vp) != 0) {
perror("pthread_join error");
exit (__LINE__);
}
if (pthread_join(tid2, &vp) != 0) {
perror("pthread_join error");
exit (__LINE__);
}
printf("Parent process sees x: %d\n",x);
return 0;
}

gcc pthread_rwlock.c -o rwlock -pthread -Wall-Werror

./rwlock

reader_lock: x: 0

Processus Parent voit x: 3

Quelques informations sur mon système, le système est en 64 bits, fonctionnant sur une version 64 bits de Linux v3.11.2
Pourquoi sont deux mutex nécessaires pour obtenir une synchronisation? Ai-je raté quelque chose?

OriginalL'auteur Amit | 2013-10-20