linux线程笔记5

2017-01-05 20:14:45来源:CSDN作者:lu_k120人点击

线程互斥读写锁

线程使用互斥锁缺乏读并发性,当读操作较多,写操作较少时,可使用读写锁提高线程读并发性

读写锁数据类型

pthread_rwlock_t

读写锁创建和销毁

#include <pthread.h>
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,const pthread_rwlockattr_t *restrict attr);
int pthread_rwlock_destroy(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:读写锁

例子:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
pthread_rwlock_t rwlock;
int main(int argc,char *argv[])
{
	if(argc < 3){
		printf("-usage:%s [r/w] [r/w]/n",argv[0]);
		exit(1);
	}
	pthread_rwlock_init(&rwlock,NULL);
	if(!strcmp("r",argv[1])){
		//加读锁
		if(pthread_rwlock_rdlock(&rwlock)!=0){
			printf("first read lock failure/n");
		}else{
			printf("first read lock success");
		}
	}else if(!strcmp("w",argv[1])){
		//加写锁
		if(pthread_rwlock_wrlock(&rwlock)!=0){
			printf("first write lock failure/n");
		}else{
			printf("first write lock success");
		}
	}	

	if(!strcmp("r",argv[2])){
		//加读锁
		if(pthread_rwlock_rdlock(&rwlock)!=0){
			printf("second read lock failure/n");
		}else{
			printf("second read lock success");
		}
	}else if(!strcmp("w",argv[2])){
		//加写锁
		if(pthread_rwlock_wrlock(&rwlock)!=0){
			printf("second write lock failure/n");
		}else{
			printf("second write lock success");
		}
	}
	pthread_rwlock_unlock(&rwlock);
	pthread_rwlock_unlock(&rwlock);

	return 0;
}
编译:gcc -lpthread **.c -o test运行:./test r rfirst read lock successsecond read lock succes./test r wfirst read lock success阻塞./test w rfirst write lock successsecond read lock failure./test w wfirst write lock successsecond writelock failure
分析归纳:第一次读   成功   第二次读   成功读和读:不排斥第一次读   成功   第二次写   阻塞第一次写   成功   第二次读   失败
读和写 排斥第一次写   成功   第二次写   失败
写和写:排斥读写锁特性:读和读:不排斥读和写/写和读:排斥写和写:排斥

例子:

account.h#ifndef  _ACCOUNT_H#define  _ACCOUNT_Htypedef struct{	int   code; //账户	double  balance;//余额
	pthread_rwlock_t rwlock;//定义读写锁}Account;//创建账户extern Account* create_account(int code,double balance);//创建账户extern void destory_account(Account *a);//取款extern double withdraw(Account *a,double amt);//存款extern double deposit(Account *a,double amt);//查看账户余额extern double get_balance(Account *a);#endifaccount.c#include "account.h"#include <malloc.h>#include <assert.h>#include <string.h>//创建账户Account* create_account(int code,double balance){	Account *a = (Account *)malloc(sizeof(Account));	assert(a !=NULL);	a->code = code;	a->balance = balance;
	pthread_rwclock_init(&a->rwlock,NULL);//对读写锁进行初始化	return a;}//销毁账户void destory_account(Account *a){	assert(a != NULL);
	pthread_rwclock_destroy(&a->rwlock);//销毁读写锁	free(a);}//取款double withdraw(Account *a,double amt){
	assert(a != NULL);
	pthread_rwlock_wrlock(&a->rwlock);//加写锁	if(amt < 0 || amt > a->balance){
		pthread_rwlock_unlock(&a->rwlock);//释放读写锁		return 0.0;	}	double balance = a->balance;	sleep(1);	balance -= amt;	a->balance = balance;
	pthread_rwlock_unlock(&a->rwlock);//释放读写锁	return amt;}//存款double deposit(Account *a,double amt){	assert(a!=NULL);
	pthread_rwlock_wrlock(&a->rwlock);//加写锁	if(amt < 0){
		pthread_rwlock_unlock(&a->rwlock);//释放读写锁		return 0.0;	}	double balance = a->balance;	sleep(1);	balance += amt;
	pthread_rwlock_unlock(&a->rwlock);//释放读写锁	return amt;}//查看账户余额double get_balance(Account *a){	assert(a != NULL);
	pthread_rwlock_rdlock(&a->rwlock);	double balance = a->balance;
	pthread_rwlock_unlock(&a->rwlock);	return balance;}account_test.c#include "account.h"#include <pthread.h>#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct{char name[20];Account *account;double amt;}OperArg;//取款void *withdraw_fn(void *arg){ 	OperArg *oa = (OperArg *)arg;	double amt = withdraw(oa->account,oa->amt);	printf("%8s(0x%lx) withdraw %f from account %d/n",oa->name,pthread_self,amt,oa->account->code);	return (void*)0;}//存款void *deposit_fn(void *arg){	OperArg *oa = (OperArg *)arg;	double amt = deposit(oa->account,oa->amt);	printf("%8s(0x%lx) 	deposit %f from account %d/n",oa->name,pthread_self,amt,oa->account->code);	return (void*)0;}//查询void *check_fn(void *arg){	return (void *)0;}int main(void){	int err;	pthread_t boy,girl;	Acount *a = create_account(100001,10000);	OperArg o1,o2;	strcpy(o1.name,"boy");	o1.amt = 10000;	o1.account = a;		strcpy(o2.name,"girl");	o2.account = a;	o2.amt = 10000;	//启动两个子线程(boy、girl线程)同时操作同一个银行账户	if((err = pthread_create(&boy,NULL,withdraw_fn,(void *)&o1)) != 0){		perror("prthread create error");	}	if((err = pthread_create(&girl,NULL,withdraw_fn,(void *)&o2)) != 0){		perror("prthread create error");	}	pthread_join(boy,NULL);	pthread_join(girl,NULL);	printf("account balance:%f/n",get_balance(a));	destroy_account(a);	return 0;}
编译:gcc -lpthread accunt.c account_test.c -o account_test

运行:./account_test

结果: girl(0xb6fesd0)withdraw 10000.000000from account 100001

boy(0xb77esd0)withdraw 0.000000 from account 100001

account balance:0.0000;
加上读写锁,运行正常

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台