多线程的互斥—读写锁
//account.h #ifndef _ACCOUNT_H #define _ACCOUNT_H #include <pthread.h> typedef struct{ int code; double balance; //定义一把互斥锁,用来对多线程操作的银行账户(共享资源)进行加锁(保护)的 /* 建议一把互斥锁和一个共享资源(银行账户)绑定,尽量不要设置成全局变量,否则可能出现 一把互斥锁去锁几百个账户(即一个线程获得锁,其他线程将阻塞),导致并发性的降低 */ pthread_rwlock_t rwlock; }Account; //创建账户 extern Account *create_account(int code, double balance); //销毁账户 extern void destroy_account(Account *a); //取款 extern double get_momney(Account *a, double momney); //存款 extern double save_momney(Account *a, double momney); //获得余额 extern double get_balance(Account *a); #endif
//accout.c #include "account.h" #include <stdlib.h> #include <stdio.h> #include <unistd.h> //创建账户 Account *create_account(int code, double balance) { Account *a = (Account *)malloc(sizeof(Account)); if(a == NULL){ printf("create_account failed\n"); return (Account *)0; } a->code = code; a->balance = balance; if(pthread_rwlock_init(&a->rwlock, NULL) != 0){ printf("pthread_rwlock_init failed\n"); } return a; } //销毁账户 extern void destroy_account(Account *a) { if(a == NULL){ printf("destroy_account failed\n"); } if(pthread_rwlock_destroy(&a->rwlock) != 0){ printf("pthread_rwlock_destroy failed\n"); } free(a); } //取款 extern double get_momney(Account *a, double momney) { if(a == NULL){ printf("get_momney failed\n"); } pthread_rwlock_wrlock(&a->rwlock); if(momney < 0 || a->balance < momney) { printf("momney not enough\n"); pthread_rwlock_unlock(&a->rwlock); return 0.0; } double balance = a->balance; sleep(1); balance = balance - momney; a->balance = balance; pthread_rwlock_unlock(&a->rwlock); return momney; } //存款 extern double save_momney(Account *a, double momney) { if(a == NULL){ printf("save_momney failed\n"); } pthread_rwlock_wrlock(&a->rwlock); if(momney < 0){ pthread_rwlock_unlock(&a->rwlock); return 0.0; } double balance = a->balance; sleep(1); balance = balance + momney; a->balance = balance; pthread_rwlock_unlock(&a->rwlock); return momney; } //获得余额 extern double get_balance(Account *a) { if(a == NULL){ printf("get_balance failed\n"); } pthread_rwlock_wrlock(&a->rwlock); double balance = a->balance; pthread_rwlock_unlock(&a->rwlock); return balance; }
//account_test.c #include <stdio.h> #include <pthread.h> #include "account.h" #include <string.h> #include <stdlib.h> /* void *memcpy(void *dest, const void *src, size_t n); */ /* int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); */ typedef struct{ Account *account; char name[20]; double momney; }operArg; void *getmomney_fn(void *arg) { operArg *o = (operArg *)arg; double momney = get_momney(o->account, o->momney); printf("%s from %d getmomney %f\n",o->name, o->account->code, momney); return (void *)0; } int main() { pthread_t boy,girl; Account *a = create_account(1001,10000); operArg o1,o2; o1.account = a; o1.momney = 10000; memcpy(o1.name, "boy", sizeof("boy")); o2.account = a; o2.momney = 10000; memcpy(o2.name, "girl", sizeof("girl")); if(pthread_create(&boy, NULL, getmomney_fn, (void *)&o1) < 0){ printf("pthread_create failed\n"); exit(1); } if(pthread_create(&girl, NULL, getmomney_fn, (void *)&o2) < 0){ printf("pthread_create failed\n"); exit(1); } pthread_join(boy, NULL); pthread_join(girl, NULL); printf("get balance = %f\n",get_balance(a)); destroy_account(a); return 0; }