IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 互斥锁、读写锁的简单应用,程序示例 -> 正文阅读

[C++知识库]互斥锁、读写锁的简单应用,程序示例

mutex1.h

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

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

    //定义读写锁
    pthread_rwlock_t rwlock;
};
//创建用户
 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<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);
    return a;
}

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

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

}

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

    //加写锁
    pthread_rwlock_wrlock(&a->rwlock);
   
    if(amt<0||amt>a->balance)
    {
        //释放互斥锁
        //pthread_mutex_unlock(&a->mutex);

        //释放读写(写)锁
        pthread_rwlock_unlock(&a->rwlock);
        return 0.0;
    }
    double balance=a->balance;

    sleep(1);

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

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

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

    pthread_rwlock_wrlock(&a->rwlock);
    if(amt<0)
    {
        //pthread_mutex_unlock(&a->mutex);

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

    pthread_rwlock_unlock(&a->rwlock);
    return amt;
}

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

    pthread_rwlock_rdlock(&a->rwlock);
    double balance=a->balance;
    //pthread_mutex_unlock(&a->mutex);

    pthread_rwlock_rdlock(&a->rwlock);
    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;
}

?

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-09 18:05:39  更:2022-04-09 18:09:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:54:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码