读写锁(读写者问题)

先来了解一下什么是自旋锁
自旋锁是一种保护共享资源的锁机制。与互斥锁类似,无论是互斥锁还是自旋锁,在任何时刻都只有一个持有者。但是两者在调度机制上略有不同。对于互斥锁,如果锁资源已经被占用,则锁资源的申请者只能挂起等待。但是对于自旋锁而言,如果锁资源已经被占用,则锁资源的申请者就一直循环在那里看该自旋锁是否被该锁的保持者释放。
读写锁:读写锁实际是一种特殊的自旋锁,它把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作。这种锁相对于自旋锁而言,能提高并发性,因为在多处理器系统中,它允许同时有多个读者来访问共享资源,最大可能的读者数为实际的逻辑CPU数。写者是排他性的,⼀个读写锁同时只能有⼀个写者或多个读者(与CPU数相关),但不能同时既有读者又有写者。
二元信号量以及互斥锁就属于挂起等待锁。

读写锁的三种状态:读模式加锁,写模式加锁,不加锁。
当读写锁是写加锁时,在这个锁被解锁之前所有企图对它加锁的线程都将被阻塞。
当读写锁是读加锁时,在这个锁被解锁之前所有企图以读模式对它加锁的线程都可以获得访问权;以写模式对它加锁的线程将被阻塞,并且阻塞随后的读模式加锁线程。这样可以避免读模式长期占用锁,而写模式请求得不到满足的情况。
读写者问题为例使用读写锁,先来了解一下读写者问题
读者—-读者(没有关系)
读者—-写者(同步与互斥)
写者—-写者(互斥关系)
读写锁的创建:
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,const pthread_rwlockattr_t *restrict attr)
读写锁的类型:pthread_rwlock_t
参数1:读写锁rwlock的地址
参数2:读写锁rwlock的属性,设置为NULL
读模式加锁:
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)
没有写者保持锁且没有被阻塞的写者时读模式加锁成功,返回0;否则自旋式等待锁。
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
若没有写者保持锁且没有被阻塞的写者时读模式加锁成功,返回0;否则加锁失败立即返回。

写模式加锁:
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
没有读者或写者保持读写锁,则写模式加锁成功,返回0;否则该线程自旋式等待该锁。
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
没有读者或写者保持读写锁,则写模式加锁成功,返回0;否则加锁失败立即返回。
读写锁的释放:
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

读写锁的销毁:
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
程序示例:

#include
#include
pthread_rwlock_t rwlock;
int buf = 0;
void *reader(void *arg)
{
    int ret;
    while(1)
    {
        if((ret = pthread_rwlock_tryrdlock(&rwlock))!=0)
        {
            printf("writer is writing, %u, %s\n",pthread_self(),strerror(ret));
        }
        else
        {
            printf("reader is reading %u, %d\n",pthread_self(),buf);
            pthread_rwlock_unlock(&rwlock);
        }
        sleep(1);
    }
}
void *writer(void *arg)
{
    int ret,i = 0;
    while(1)
    {
        if((ret = pthread_rwlock_trywrlock(&rwlock))!=0)
        {
            printf("reader is reading %u, %s\n",pthread_self(),strerror(ret));
        }
        else
        {
            buf = i;
            printf("writer is writing %u, %d\n",pthread_self(),buf);
            i++;
            pthread_rwlock_unlock(&rwlock);
        }
        sleep(1);
    }
}
int main()
{
    pthread_rwlock_init(&rwlock,NULL);
    pthread_t id1,id2;
    pthread_create(&id1,NULL,reader,NULL);
    pthread_create(&id2,NULL,writer,NULL);
    pthread_join(id1,NULL);
    pthread_join(id2,NULL);
    pthread_rwlock_destroy(&rwlock);
    return 0;
}

读写锁(读写者问题)_第1张图片

你可能感兴趣的:(linux)