您的位置:首页 > 运维架构 > Linux

Linux线程浅析[线程的同步和互斥之线程读写锁]

2017-03-31 22:27 267 查看

Linux线程浅析[线程的同步和互斥之线程读写锁]

读写锁的出现是为了解决互斥锁的弊端

使用上述Linux线程浅析[线程的同步和互斥之线程互斥锁]的案例来进行解释吧,即针对上述案例中的银行存取款的互斥锁,当一个账户去访问的时候,另外一个账户其实就需要被阻塞,但是现实中往往会有这样一种情况,一个人去存,但是其余的人是去查询,如果存的人获取了锁,那么查询的人就需要被阻塞,这就导致了查询效率极低的这样的一种情况

什么是读写锁:

 概念:

读写锁实际是一种特殊的自旋锁,它把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作。

 读写锁的使用场景:

 

线程互斥——读写锁

线程使用互斥锁缺乏读并发性

当读操作较多时,写操作较少时,可以使用读写锁来提高线程读并发性

读写锁:
pthread_rwlock_t


读写锁的相关函数:

#include<pthread.h>
int pthread_wrlock_init(pthread_rwlock_t *restrict rwlock,const     pthread_rwlockattr_t *restrict attr);
int ptrhead_wrlock_destory(pthread_rwlock_t *rwlock)
成功:返回0,出错返回错误编码
参数:
rwlock:读写锁
attr:读写锁属性


读写锁加锁和加写锁

#include<pthread.h>
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)
功能:加读锁
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
功能:加写锁
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
功能:释放锁
返回:成功返回0,失败返回错误编码
参数:rwlock:读写锁


 如下表格所示:

类型readlockwritelock
readlock读锁和读锁不排斥先写锁成功,读锁失败
writelock先读锁成功,写锁阻塞先写成功,后写失败
 表格总结(同一把读写锁):

 1:如果一个函数上了读锁,两个线程一起调用的时候是不会发生排斥现象的(不排斥)

 2:如果一个函数上了读锁,另一个函数上了写锁,那么线程一先调用读锁函数,线程二再调用写锁函数的时候,这个时候线程二是会阻塞住的(排斥)

3:如果一个函数上了读锁,另外一个函数上了写锁,当线程一先调用写锁函数,线程二再调用读锁函数的时候,这个时候线程二是会加锁失败(排斥)

4:一个函数上了写锁,两个线程同时调用写锁函数.第一个调用成功,第二个会失败(排斥)

那么通过读写锁的形式对原来互斥锁的银行案例进行修改:

/*
* ===========================================================================
*
*       Filename:  account.h
*    Description:
*        Version:  1.0
*        Created:  2017年03月28日 22时04分18秒
*       Revision:  none
*       Compiler:  gcc
*         Author:   (),
*        Company:
*
* ===========================================================================
*/

#ifndef __ACCOUNT_H_
#define __ACCOUNT_H_
//声明银行账户的结构体
//引用pthread头文件.方便后面加锁
#include<pthread.h>
typedef struct{
int code;
double balance;
//将锁声明在结构体中,有助于每一个这样的结构体都有一把锁,那么在操作的时候,有利于优化并发效果
//pthread_mutex_t pthreadmutex;
pthread_rwlock_t pthreadrwlock;
}Account;

//创建银行账户
extern Account* create_account(int code,double balance);

//销毁一个账户
extern void destory_account(Account* account);

//存款
extern double withdraw(Account* account,double amt);

//取款
extern double deposit(Account* a,double amt);

//查看账户余额
extern double get_balance(Account* account);

#endif


/*
* ===========================================================================
*
*       Filename:  account.c
*    Description:
*        Version:  1.0
*        Created:  2017年03月30日 21时16分28秒
*       Revision:  none
*       Compiler:  gcc
*         Author:   (),
*        Company:
*
* ===========================================================================
*/

#include"account.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
#include<assert.h>
#include<pthread.h>

//static pthread_mutexattr_t attr;
/*
*创建一个账户
*返回这个账户的指针
*
* */
extern Account* create_account(int code,double balance){
Account* account = (Account*)malloc(sizeof(Account));
assert(account !=NULL);
account->code = code;
account->balance = balance;
//初始化锁的过程
//pthread_mutexattr_init(&attr);
//pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_NORMAL);
//pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
//pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_ERRORCHECK);
//pthread_mutex_init(&account->pthreadmutex,NULL);
//pthread_mutex_init(&account->pthreadmutex,&attr);

//初始化读写锁
pthread_rwlock_init(&account->pthreadrwlock,NULL);

return account;
}
/* *
*销毁一个账户
* */
extern void destory_account(Account* account){
assert(account!=NULL);
free(account);
//销毁锁的过程
//pthread_mutexattr_destroy(&attr);
//pthread_mutex_destroy(&account->pthreadmutex);
//
//销毁读写锁
pthread_rwlock_destroy(&account->pthreadrwlock);
}

/* *
*取款,返回的是账户的余额
*
* */
extern double withdraw(Account * account,double amt){
assert(account != NULL);
//上锁的过程
//pthread_mutex_lock(&account->pthreadmutex);
//上读写锁(读锁)

pthread_rwlock_wrlock(&account->pthreadrwlock);

if(amt < 0 || amt > account->balance){
//解锁的过程
//pthread_mutex_unlock(&account->pthreadmutex);
//
//解读写锁
pthread_rwlock_unlock(&account->pthreadrwlock);
return 0.0;
}
int balance = account -> balance;
sleep(1);
int result = balance - amt;
account ->balance = result;
//解锁的过程
//pthread_mutex_unlock(&account->pthreadmutex);
//
//解读写锁
pthread_rwlock_unlock(&account->pthreadrwlock);
return amt;
}
/* *
*存款,返回的也是账户的余额
*
* */
extern double deposit(Account* account,double amt){
assert(account != NULL);
//上锁的过程
//pthread_mutex_lock(&account->pthreadmutex);
//上读写锁(读锁)
pthread_rwlock_wrlock(&account->pthreadrwlock);
if(amt < 0){
//解锁的过程
//pthread_mutex_unlock(&account->pthreadmutex);
//解读写锁
pthread_rwlock_unlock(&account->pthreadrwlock);
return 0.0;
}
int balance = account ->balance;
sleep(2);
int result = balance + amt;
account->balance = result;
//解锁的过程
//pthread_mutex_unlock(&account->pthreadmutex);
//解读写锁
pthread_rwlock_unlock(&account->pthreadrwlock);
return result;
}

/* *
*获取的就是这个账户的余额
*
* */
extern double get_balance(Account* account){
assert(account !=NULL);
//上读写锁(读锁)
pthread_rwlock_rdlock(&account->pthreadrwlock);
int result = account->balance;
//解决读写锁
pthread_rwlock_unlock(&account->pthreadrwlock);
return result;
}


其他部分的执行代码在互斥锁中有,所以在这里就不去赘述了.

欢迎持续访问博客

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux 线程 读写锁