互斥锁、读写锁、信号量(实现互斥)的简单应用,程序示例

mutex1.h

 #ifndef __ACOUNT_H__
#define __ACOUNT_H__
#include <pthread.h>
#include<semaphore.h>
struct Account
{
    int code;   
    double balance;  //账户余额

    //定义一把互斥锁,用来对多线程操作的
    //银行账户(共享资源)进行加锁保护的
    //建议互斥锁用来锁定一个账户(共享资源),和账户绑定在一起
    //尽量不设置为全局变量,否则可能出现一把锁去锁定
    //几百个账户,导致并发性能降低
    //pthread_mutex_t mutex;

    //定义读写锁
    //pthread_rwlock_t rwlock;

    //定义信号量
    sem_t sem;

    /* PV原语操作:
        sem_wait() 相当于P(1)操作
        sem_post() 相当于V(1)操作
    */
    
};
//创建用户
 Account* create_account(int code,double balance);

//销毁账户
void destroy_account(Account* a);

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

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

//查看当前余额
double get_balance(Account* a);

#endif

 mutex1.cpp

 #include"mutex1.h"
#include <cstdlib>
#include <pthread.h>
#include <semaphore.h>
#include<string.h>
#include<unistd.h>
//创建账户
Account* create_account(int code,double balance)
{
    Account* a=(Account*) malloc(sizeof(Account));
    a->code=code;
    a->balance=balance;
    //对互斥锁进行初始化
    //pthread_mutex_init(&a->mutex,NULL);

    //对读写锁初始化
    //pthread_rwlock_init(&a->rwlock,NULL);

    //对信号量进行初始化,初始值为1
    sem_init(&a->sem,0,1);

    return a;
}

//销毁用户
void destroy_account(Account *a)
{
    //销毁互斥锁
    //pthread_mutex_destroy(&a->mutex);

    //销毁读写锁
    //pthread_rwlock_destroy(&a->rwlock);

    //销毁信号量
    sem_destroy(&a->sem);
    free(a);

}

//取款
double withdraw(Account* a,double amt)
{
    //对共享资源加锁
    //对共享资源操作的临界区(加锁到解锁的区域)
    //pthread_mutex_lock(&a->mutex);

    //加写锁
    //pthread_rwlock_wrlock(&a->rwlock);
   
    //使用信号量来实现互斥,P(1)操作
    sem_wait(&a->sem);
    if(amt<0||amt>a->balance)
    {
        //释放互斥锁
        //pthread_mutex_unlock(&a->mutex);

        //释放读写(写)锁
        //pthread_rwlock_unlock(&a->rwlock);

        //V(1)操作
        sem_post(&a->sem);
        return 0.0;
    }
    double balance=a->balance;

    sleep(1);

    balance-=amt;
    a->balance=balance;
    //释放互斥锁
    //pthread_mutex_unlock(&a->mutex);

    //释方读写(写)锁
    //pthread_rwlock_unlock(&a->rwlock);

    //V(1)操作
    sem_post(&a->sem);
    return amt;;
 
}

//存款
double deposit(Account *a, double amt)
{
    //pthread_mutex_lock(&a->mutex);

    //pthread_rwlock_wrlock(&a->rwlock);

    //P(1)操作
    sem_wait(&a->sem);
    if(amt<0)
    {
        //pthread_mutex_unlock(&a->mutex);

        //pthread_rwlock_wrlock(&a->rwlock);

        sem_post(&a->sem);
        return 0.0;
    }
    double balance=a->balance;
    sleep(1);
    balance+=amt;
    a->balance=balance;
    //pthread_mutex_unlock(&a->mutex);

    //pthread_rwlock_unlock(&a->rwlock);

    sem_post(&a->sem);
    return amt;
}

//查看当前余额
double get_balance(Account *a)
{
    //pthread_mutex_lock(&a->mutex);

    //pthread_rwlock_rdlock(&a->rwlock);

    sem_wait(&a->sem);
    double balance=a->balance;
    //pthread_mutex_unlock(&a->mutex);

    //pthread_rwlock_rdlock(&a->rwlock);

    sem_post(&a->sem);
    return balance;
}

main.cpp

 #include "mutex1.h"
#include <cstdio>
#include<iostream>
#include <pthread.h>
#include <string>
using namespace std;
pthread_mutex_t mt;
//pthread_mutex_init(&mt,NULL);
struct OperArg   //操作者信息
{
    string name;
    Account *account;
    double amt;

};
//定义取款操作的线程运行函数
void* withdraw_fn(void* arg) 
{
     OperArg* oa=(OperArg*)arg;
     double amt=withdraw(oa->account,oa->amt);
     pthread_mutex_lock(&mt);
     cout<<oa->name<<" "<<
        " withdraw "<<amt<< " from account "<<
        oa->account->code<<endl;   //amt 是取款函数的返回值
    pthread_mutex_unlock(&mt);


    return (void*)0;
}

//定义存款操作的线程运行函数
void* deposit_fn(void* arg)
{
    OperArg* oa=(OperArg*)arg;
    double amt=deposit(oa->account,oa->amt);
    cout<<"name:"<<oa->name<<" "<<pthread_self()<<
        " withdraw "<<amt<< " from account "<<
        oa->account->code<<endl;   //amt 是取款函数的返回值

    
    return (void*)0;
}

//定义检查银行账户的线程运行函数
void* check_fn(void* arg)
{
    return (void*)0;
}

int main()
{
    int err;
    pthread_t boy,girl;
    Account *a=create_account(100001,10000); //创建银行用户

    OperArg o1,o2;   //操作的两个用户,boy,girl
    
    o1.name="boy";
    o1.account=a;
    o1.amt=10000;

    o2.name="girl";
    o2.account=a;
    o2.amt=10000;

    //启动两个子线程(boy和girl线程)
    //同时去操作一个银行用户
    err=pthread_create(&boy,NULL,withdraw_fn,(void*)&o1);
    if(err!=0)
    {
        perror("create error");
    }

    err=pthread_create(&girl,NULL,withdraw_fn,(void*)&o2);
    if(err!=0)
    {
        perror("create error");
    }

    pthread_join(boy,NULL);
    
    pthread_join(girl,NULL);

    //两个子线程操作完后,主线程去查看余额
    cout<<"account balance: "<<get_balance(a)<<endl;
    destroy_account(a);


    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值