pthread中的读/写锁

我正在学习pthread并遇到了读者作家锁。 场景非常简单; 一个全局变量被所有线程共享,读者继续打印同一个全局变量的当前值,而writer将更新同一个变量。 我可以通过使用两个互斥锁(pthread_mutex_t)来实现此同步,但我想使用“一个”读写器锁来实现相同的结果。 但是,使用一个读写器锁,如此处所示(程序的输出,如下),读者只能看到x的第一个值,并且看不到对全局变量的任何更新。 请点亮这里。

码:

#include  #include  #include  #include  #include  #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

父进程看到x:3

当线程获取锁时,尝试获取相同锁的其他线程将被挂起,直到第一个线程释放锁。

这里发生的是你的读者线程启动,获取锁定,并进入for/poll循环。

编写器线程启动,尝试获取读取器线程已经占用的锁,并在pthread_rwlock_wrlock上保持阻塞状态。

您实际想要做的是在访问共享变量的代码之前和之后放置lock/unlock

 thread_rwlock_rdlock(p); newx = ACCESS_ONCE(x); thread_rwlock_unlock(p); ... thread_rwlock_wrlock(p); ACCESS_ONCE(x)++; thread_rwlock_unlock(p);