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

发布时间 2023-03-26 23:30:25作者: 踏浪而来的人

同步:

//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;
}