pthread中的读取器/写入器锁定 [英] reader/writer lock in pthread

查看:79
本文介绍了pthread中的读取器/写入器锁定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习pthread,并遇到读者写作者锁.场景非常简单;一个由所有线程共享的全局变量,读取器将继续打印该相同全局变量的当前值,而写入器将更新同一变量.我可以通过使用两个互斥对象(pthread_mutex_t)来实现这种同步,但是我想使用一个"读写器锁来实现相同的结果.但是,使用一个读写器锁(如此处所示(程序的输出,在下面)),读者只能看到x的第一个值,而看不到全局变量的任何更新.请在这里放些灯光.

I'm learning pthread and came across reader writer lock. The scenario is very simple; a global variable being shared by all the threads, reader keeps printing the current value of that same global variable, while writer will update the same variable. I can achieve this synchronization by using two mutexes (pthread_mutex_t), but I want to use "one" reader-writer lock for achieving this same result. However, with one reader-writer lock, as can be seen here(output of the program, below), reader only sees the first value of x and doesn't sees any updates to the global variable. Please throw some light here.

代码:

#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

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

./rwlock

reader_lock:x:0

reader_lock: x: 0

父进程看到x:3

推荐答案

当一个线程获取一个锁时,试图获取相同锁的其他线程将被挂起,直到第一个线程释放该锁为止.

When a thread acquires a lock, other threads trying to acquire the same lock will be suspended until the first thread releases the lock.

这里发生的是您的阅读器线程启动,获取锁并进入for/poll循环.

What is happening here is that your reader thread starts, acquires the lock, and enters the for/poll loop.

写程序线程启动,尝试获取读线程已获取的锁,并在pthread_rwlock_wrlock上保持阻塞.

The writer thread starts, tries to acquire the lock which was already taken by the reader thread, and remains blocked on pthread_rwlock_wrlock.

您真正想要做的是将lock/unlock放在访问共享变量的代码之前和之后.

What you actually want to do is to put your lock/unlock right before and after the code where you access your shared variable.

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

这篇关于pthread中的读取器/写入器锁定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆