首页 > 其他分享 >多线程的同步和互斥—线程的信号量

多线程的同步和互斥—线程的信号量

时间:2023-03-26 23:34:37浏览次数:34  
标签:Account balance get double 信号量 互斥 sem 多线程 momney

同步:

//account.h
#ifndef     _ACCOUNT_H
#define     _ACCOUNT_H
#include <pthread.h>
#include <semaphore.h>


typedef struct{
    int code;
    double balance;    
    //定义一把互斥锁,用来对多线程操作的银行账户(共享资源)进行加锁(保护)的
    
    /* 建议一把互斥锁和一个共享资源(银行账户)绑定,尽量不要设置成全局变量,否则可能出现
    一把互斥锁去锁几百个账户(即一个线程获得锁,其他线程将阻塞),导致并发性的降低 
    */
    sem_t sem;
}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;
    sem_init(&a->sem, 0, 1);//信号量初始为1
    
    return a;
}

//销毁账户
extern void destroy_account(Account *a)
{
    if(a == NULL){
        printf("destroy_account failed\n");
    }
    
    sem_destroy(&a->sem);
    free(a);
}

//取款
extern double get_momney(Account *a, double momney)
{
    if(a == NULL){
        printf("get_momney failed\n");
    }
    
    //P
    sem_wait(&a->sem);
    if(momney < 0 || a->balance < momney)
    {
        printf("momney not enough\n");
        //V
        sem_post(&a->sem);
        return 0.0;
    }
    
    double balance = a->balance;
    sleep(1);
    balance = balance - momney;
    a->balance = balance;
    //V
    sem_post(&a->sem);
    
    return momney;
}


//存款
extern double save_momney(Account *a, double momney)
{
    if(a == NULL){
        printf("save_momney failed\n");
    }
    
    //P
    sem_wait(&a->sem);
    if(momney < 0){
        //V
        sem_post(&a->sem);
        return 0.0;
    }
    
    double balance = a->balance;
    sleep(1);
    balance = balance + momney;
    a->balance = balance;
    //V
    sem_post(&a->sem);
    
    return momney;
}


//获得余额
extern double get_balance(Account *a)
{
    if(a == NULL){
        printf("get_balance failed\n");
    }
    
    //P
    sem_wait(&a->sem);
    double balance = a->balance;
    //V
    sem_post(&a->sem);
    
    return balance;
}

 

同步:

//cal.c

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>


typedef struct
{
    int res;
    
    sem_t sem;
}ResArg;

void *cal_fn(void *arg)
{
    ResArg *result = (ResArg *)arg;
    int i = 0;
    int sum = 0;
    for(i = 0;i <101; i++){
        sum +=i;
    }
    result->res = sum;
    
    sleep(1);
    //V
    sem_post(&result->sem);
    printf("v operate\n");
    
    
    (void *)0;
}

void *get_fn(void *arg)
{
    ResArg *result = (ResArg *)arg;
    
    //P
    sem_wait(&result->sem);
    printf("P operate\n");
    printf("reslt = %d\n",result->res);
    
    (void *)0;
}

int main(void)
{
    int err;
    pthread_t cal,get;
    ResArg  r;
    sem_init(&r.sem, 0, 0);//初始值为0
    
    if(pthread_create(&cal,NULL,cal_fn,(void *)&r) != 0){
        printf("cal pthread creat fail\n");
    }
    
    if(pthread_create(&get,NULL,get_fn,(void *)&r) != 0){
        printf("get pthread creat fail\n");
    }
    
    pthread_join(cal,NULL);
    pthread_join(get,NULL);
    
    sem_destroy(&r.sem);
    
    return 0;
}

 

标签:Account,balance,get,double,信号量,互斥,sem,多线程,momney
From: https://www.cnblogs.com/zj-studyrecoding/p/17259966.html

相关文章

  • Python多任务-多线程-多进程-协程-进阶学习
    --多任务-多线程-多进程-协程-进阶学习--文中所提到的案例参考:GITHUB中项目文件夹https://github.com/FangbaiZhang/Python_advanced_learning/tree/master/02_Python_ad......
  • Task 类 多线程
    Task类定义命名空间: System.Threading.Tasks程序集:System.Runtime.dll表示一个异步操作publicclassTask:IAsyncResult,IDisposable继承  Object->Task......
  • 多线程的互斥—读写锁
    //account.h#ifndef_ACCOUNT_H#define_ACCOUNT_H#include<pthread.h>typedefstruct{intcode;doublebalance;//定义一把互斥锁,用......
  • 共享锁、排他锁、互斥锁、悲观锁、乐观锁、行锁、表锁、页面锁、不可重复读、丢失修改
    共享锁(S锁)又称为读锁,可以查看但无法修改和删除的一种数据锁。如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排它锁。获准共享锁的事务只能读数据,不能修......
  • 多线程的并发—互斥锁(互斥量)
    //account.h#ifndef_ACCOUNT_H#define_ACCOUNT_H#include<pthread.h>typedefstruct{intcode;doublebalance;//定义一把互斥锁,用......
  • 多线程操作共享资源(如全局变量)原理
    CPU对变量的计算分为三个步骤:1.从内存读取变量到寄存器(如add寄存器)2.将读取到的变量进行计算3.将寄存器中计算的值写入内存 如有两个线程(线程1和线程......
  • Java多线程
    一、多线程简介 Java多线程是指在一个程序中同时执行多个线程(线程就是一条执行路径)。Java中的多线程可以提高程序的运行效率和并发性,通常用于执行一些耗时的操作或需要同......
  • 多线程sigpipe
    之前记录过socket读写异常相关情况,socket链接错误以及原因以及信号相关处理:多线程信号处理目前调试引擎时候出现了 错误;signalSIGPIPE,Brokenpipe一开始以为是没......
  • 多线程
    一、线程1、概念线程在一个进程的内部,要同时干多件事,就需要同时运行多个“子任务”,我们把进程内的这些“子任务”叫做线程是操作系统能够进行运算调度的最小单位。它......
  • 2 - 线程 - Windows 10 - CPython 解释器 - 多线程并行(实际并发)
    @目录一、线程和进程介绍进程基本概念面向线程设计的系统内部解析-用户态/内核态线程基本概念二、对进程线程并发并行的实际运行过程的理解:CPython多线程争抢GIL——......