gpt4 book ai didi

c - pthread 中的读/写锁

转载 作者:太空狗 更新时间:2023-10-29 15:24:20 25 4
gpt4 key购买 nike

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

代码:

#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

Parent process sees 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);

关于c - pthread 中的读/写锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19482648/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com