Linux多线程(六)互斥锁

xiaoxiao2021-02-28  46

     线程实际运行过程中,我们经常需要多个线程保持同步。这时可以用互斥锁来完成任务;互斥锁的使用过程中,主要有pthread_mutex_init,pthread_mutex_destory,pthread_mutex_lock,pthread_mutex_unlock四个函数。

int pthread_mutex_init(pthread_mutex_t *restrict mutex,              const pthread_mutexattr_t *restrict attr);

 

该函数用于C函数的多线程编程中,互斥锁的初始化。

  pthread_mutex_init()函数是以动态方式创建互斥锁的,参数attr指定了新建互斥锁的属性。如果参数attr为NULL,则使用默认的互斥锁属性,默认属性为快速互斥锁 。互斥锁的属性在创建锁的时候指定,在LinuxThreads实现中仅有一个锁类型属性,不同的锁类型在试图对一个已经被锁定的互斥锁加锁时表现不同。

  pthread_mutexattr_init()函数成功完成之后会返回零,其他任何返回值都表示出现了错误。

  函数成功执行后,互斥锁被初始化为锁住态。

       int pthread_mutex_lock(pthread_mutex_t *mutex)

  int pthread_mutex_unlock(pthread_mutex_t *mutex)

  int pthread_mutex_trylock(pthread_mutex_t *mutex)

  pthread_mutex_trylock()语义与pthread_mutex_lock()类似,不同的是在锁已经被占据时返回EBUSY而不是挂起等待。

实验:创建两条线程,线程的执行函数是取钱,(这里采用了互斥锁的功能,就解决了上一节介绍的访问共享资源出现的问题),本实验有3个文件,其中account.c 和 account.h 文件是模拟银行取钱,存钱,查询余额的函数,test.c为主函数。

tips:这里的互斥锁是一个局部变量,尽量少的定义成全局变量

源码如下:

account.h

/****************************/

#ifndef __ACCOUNT_H__#define __ACCOUNT_H__#include <pthread.h>typedef struct{   int code;   double balance;   pthread_mutex_t mutex;}Account;extern Account * create_account(int code,double balance);extern void destroy_account(Account *a);extern double with_draw(Account *a,double amt);extern double depoist(Account *a,double amt);extern double get_balance(Account *a)#endif

/****************************/

account.c

#include "account.h"#include <assert.h>#include <malloc.h>#include <string.h>Account *create_account(int code, double balance){   Account *r=(Account *)malloc(sizeof(Account));   assert(r!=NULL);   r->code=code;   r->balance=balance;   pthread_mutex_init(&r->mutex,NULL);   return r;}void destroy_account(Account *a){   assert(a!=NULL);   free(a);}double with_draw(Account *a, double amt){   assert(a!=NULL);   pthread_mutex_lock(&a->mutex);   if(amt > a->balance || amt<0){      pthread_mutex_unlock(&a->mutex);      return 0.0;   }   double balance=a->balance;   sleep(1);   balance = balance - amt;

   a->balance = balance;

   pthread_mutex_unlock(&a->mutex);

   return amt;}double depoist(Account *a, double amt){   assert(a!=NULL);   if(amt<0){      return 0.0;   }   pthread_mutex_lock(&a->mutex);   double balance=a->balance;   sleep(1);   balance = balance + amt;   a->balance = balance;   pthread_mutex_unlock(&a->mutex);   return amt;

}

/************************************/

test.c

/*********************************/

#include <pthread.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include "account.h"typedef struct{   char name[20];   Account *account;   double amt;}Arg;void *func_th(void *arg){    Arg *r=(Arg *)arg;    double amt=with_draw(r->account,r->amt);    printf("%8s(0x%lx) withdraw %f from account %d\n",                  r->name,pthread_self(),amt,r->account->code);    return (void*)0;}int main(int argc,char *argv[]){    int err;    pthread_t boy,girl;    Account *a=create_account(1001,10000);    Arg r1,r2;    strcpy(r1.name,"man");    r1.account=a;    r1.amt=10000;    strcpy(r2.name,"woman");

    r2.account=a;

    r2.amt=10000;    if((err=pthread_create(&boy,NULL,func_th,(void *)&r1))!=0)    {        perror("pthread create error");    }    if((err=pthread_create(&girl,NULL,func_th,(void *)&r2))!=0)    {        perror("pthread create error");    }    pthread_join(boy,NULL);    pthread_join(girl,NULL);        //打印余额   printf("the rest of the count is %f\n",get_balance(a));   //打印线程ID   printf("%lx thread finished\n",pthread_self());    return 0;

}

/****************************/

实验结果:

   woman(0x7fd78cb2f700) withdraw 10000.000000 from account 1001     man(0x7fd78d330700) withdraw 0.000000 from account 1001the rest of the count is 0.0000007fd78db33700 thread finished

转载请注明原文地址: https://www.6miu.com/read-2621336.html

最新回复(0)