0
点赞
收藏
分享

微信扫一扫

互斥量的学习

我是芄兰 2022-04-29 阅读 101
linux

为了防止出现线程某甲试图访 问一共享变量时,线程某乙正在对其进行修改。引入了互斥量

互斥量 (保护对共享变量的访问)

1.概念

2.状态

3.特点

互斥量的分配

互斥量既可以像静态变量那样分配,也可以在运行时动态创建
1.静态分配

2.动态分配

注:
1.初始化一个业已初始化的互斥量将导致未定义的行为
2

  • 动态分配于堆中的互斥量。例如,动态创建针对某一结构的链表,表中每个结构都包含一个 pthread_mutex_t 类型的字段来存放互斥量,借以保护对该结构的访问。
  • 互斥量是在栈中分配的自动变量。
  • 初始化经由静态分配,且不使用默认属性的互斥量。

加锁和解锁互斥量

函数原型

1.创建互斥锁

pthread_mutex_t mtx;
//第二个参数为 NULL,互斥锁的属性会设置为默认属性
pthread_mutex_init(&mtx, NULL);

3.获取互斥锁

pthread_mutex_lock(&mtx);

5.非阻塞调用

int err = pthread_mutex_trylock(&mtx);
if(0 != err) {
    if(EBUSY == err) {
        //The mutex could not be acquired because it was already locked.
    }
}

6.超时调用

struct timespec abs_timeout;
abs_timeout.tv_sec = time(NULL) + 1;
abs_timeout.tv_nsec = 0;

int err = pthread_mutex_timedlock(&mtx, &abs_timeout);
if(0 != err) {
    if(ETIMEDOUT == err) {
        //The mutex could not be locked before the specified timeout expired.
    }
}
struct timespec
{
    __time_t tv_sec;        /* Seconds.  */
    long int tv_nsec;       /* Nanoseconds.  */
};

7、释放互斥锁

pthread_mutex_unlock(&mtx);

8、销毁线程锁

pthread_mutex_destroy(&mtx)

互斥量的死锁

当超过一个线程加锁同一组互斥量时,就有可能发生死锁。

例,每个线程都成功地锁住一个互斥量,接着试图对已为另一线程锁定的互斥量加锁。
在这里插入图片描述
两个线程将无限期等待
有两种解决方法

注:对共享资源操作前一定要获得锁。
  完成操作以后一定要释放锁。
  尽量短时间地占用锁。
  如果有多锁, 如获得顺序是ABC连环扣, 释放顺序也应该是ABC。
  线程错误返回时应该释放它所获得的锁。

例子

保护fp指向文件中数的累加正常进行

static pthread_mutex_t mut=PTHREAD_MUTEX_INITIALIZER;

void *thr_prime(void *p)
{
    FILE *fp;
    char linebuf[linesize];
    fp =fopen(fname,"r+");   //多个线程之间相撞拿到 同一个fp 开始覆盖写操作
    if(fp == NULL)  
    {
        perror("fopen");
        exit(-1);
    }
    //加锁
    pthread_mutex_lock(&mut);
    
    fgets(linebuf,linesize,fp);
    fseek(fp,0,SEEK_SET);
    fprintf(fp,"%d\n",atoi(linebuf)+1);
    //解锁
    pthread_mutex_unlock(&mut);

    fclose(fp);
    pthread_exit(NULL);
  
}

int main()
{
    int err,i;
    pthread_t tid[thrnum];
    //main 线程 进行创建线程
    for(i=0 ; i<=thrnum ;i++)
    {
        err =pthread_create(tid + i ,NULL,thr_prime,NULL);
        if(err)
        {
            fprintf(stderr,"pthread_creat():%s\n",strerror(err));
            exit(1);
        }

    }
    //为线程收尸
    for(i =0 ; i<=thrnum ;i++)
    {
        pthread_join(tid[i],NULL);
    }
    pthread_mutex_destroy(&mut);
    exit(0);

}
举报

相关推荐

0 条评论