怎么进行基于linuxthreads2.0.1线程源码分析mutex.c

本篇文章为大家展示了怎么进行基于linuxthreads2.0.1线程源码分析mutex.c,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

创新互联建站服务项目包括平阳网站建设、平阳网站制作、平阳网页制作以及平阳网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,平阳网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到平阳省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!

mutex即互斥,用于控制多线程间同步、互斥访问资源。

相关的结构体。

   

/* Mutexes (not abstract because of PTHREAD_MUTEX_INITIALIZER).  */
typedef struct
{
 // 自旋锁
 int m_spinlock; /* Spin lock to guarantee mutual exclusion.  */
 // 用于递归加锁,即某个线程多次获取了该互斥变量。m_count记录了次数
 int m_count; /* 0 if free, > 0 if taken.  */
 // 记录谁获取了该互斥变量,在递归加锁的时候会使用这个字段
 pthread_t m_owner; /* Owner of mutex (for recursive mutexes) */
 // 互斥变量的类型,递归或非递归
 int m_kind; /* Kind of mutex */
 // 等待该互斥变量的线程队列
 struct _pthread_queue m_waiting; /* Threads waiting on this mutex.  */
} pthread_mutex_t;
// 初始化互斥变量,类型是递归或非递归
#define PTHREAD_MUTEX_INITIALIZER \
 {0, 0, 0, PTHREAD_MUTEX_FAST_NP, {0, 0}}
#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \
 {0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, {0, 0}}              

下面是实现的代码。

   
     
 
    
   

/* Linuxthreads - a simple clone()-based implementation of Posix        */
/* threads for Linux.                                                   */
/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr)              */
/*                                                                      */
/* This program is free software; you can redistribute it and/or        */
/* modify it under the terms of the GNU Library General Public License  */
/* as published by the Free Software Foundation; either version 2       */
/* of the License, or (at your option) any later version.               */
/*                                                                      */
/* This program is distributed in the hope that it will be useful,      */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of       */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        */
/* GNU Library General Public License for more details.                 */

/* Mutexes */

#include <errno.h>
#include <sched.h>
#include <stddef.h>
#include "pthread.h"
#include "internals.h"
#include "spinlock.h"
#include "queue.h"
#include "restart.h"

// 利用属性结构体初始化mutex节点
int __pthread_mutex_init(pthread_mutex_t * mutex,
                      const pthread_mutexattr_t * mutex_attr)
{
 mutex->m_spinlock = 0;
 mutex->m_count = 0;
 mutex->m_owner = NULL;
 mutex->m_kind =
   mutex_attr == NULL ? PTHREAD_MUTEX_FAST_NP : mutex_attr->mutexkind;
 queue_init(&mutex->m_waiting);
 return 0;
}
weak_alias (__pthread_mutex_init, pthread_mutex_init)

// 销毁互斥锁
int __pthread_mutex_destroy(pthread_mutex_t * mutex)
{
 int count;
 acquire(&mutex->m_spinlock);
 count = mutex->m_count;
 release(&mutex->m_spinlock);
 // 正在被使用
 if (count > 0) return EBUSY;
 return 0;
}
weak_alias (__pthread_mutex_destroy, pthread_mutex_destroy)

// 非阻塞式获取锁
int __pthread_mutex_trylock(pthread_mutex_t * mutex)
{
 pthread_t self;

 acquire(&mutex->m_spinlock);
 switch(mutex->m_kind) {
 case PTHREAD_MUTEX_FAST_NP:
   // 还没有被使用,则使用数加一,返回成功
   if (mutex->m_count == 0) {
     mutex->m_count = 1;
     release(&mutex->m_spinlock);
     return 0;
   }
   break;
 // 递归获取互斥变量
 case PTHREAD_MUTEX_RECURSIVE_NP:
   self = thread_self();
   // 等于0则说明还没有被获取过,可以直接获取,或者已经被当前线程获取了,则次数加一
   if (mutex->m_count == 0 || mutex->m_owner == self) {
     mutex->m_count++;
     mutex->m_owner = self;
     release(&mutex->m_spinlock);
     return 0;
   }
   break;
 default:
   return EINVAL;
 }
 release(&mutex->m_spinlock);
 return EBUSY;
}
weak_alias (__pthread_mutex_trylock, pthread_mutex_trylock)

// 阻塞式获取互斥变量
int __pthread_mutex_lock(pthread_mutex_t * mutex)
{
 pthread_t self;

 while(1) {
   acquire(&mutex->m_spinlock);
   switch(mutex->m_kind) {
   case PTHREAD_MUTEX_FAST_NP:
     if (mutex->m_count == 0) {
       mutex->m_count = 1;
       release(&mutex->m_spinlock);
       return 0;
     }
     self = thread_self();
     break;
   case PTHREAD_MUTEX_RECURSIVE_NP:
     self = thread_self();
     // 等于0或者本线程已经获得过该互斥锁,则可以重复获得,m_count累加
     if (mutex->m_count == 0 || mutex->m_owner == self) {
       mutex->m_count++;
       // 标记该互斥锁已经被本线程获取
       mutex->m_owner = self;
       release(&mutex->m_spinlock);
       return 0;
     }
     break;
   default:
     return EINVAL;
   }
   /* Suspend ourselves, then try again */
   // 获取失败,需要阻塞,把当前线程插入该互斥锁的等待队列
   enqueue(&mutex->m_waiting, self);
   release(&mutex->m_spinlock);
   // 挂起等待唤醒
   suspend(self); /* This is not a cancellation point */
 }
}
weak_alias (__pthread_mutex_lock, pthread_mutex_lock)

int __pthread_mutex_unlock(pthread_mutex_t * mutex)
{
 pthread_t th;

 acquire(&mutex->m_spinlock);
 switch (mutex->m_kind) {
 case PTHREAD_MUTEX_FAST_NP:
   mutex->m_count = 0;
   break;
 case PTHREAD_MUTEX_RECURSIVE_NP:
   mutex->m_count--;
   if (mutex->m_count > 0) {
     release(&mutex->m_spinlock);
     return 0;
   }
   mutex->m_count = 0; /* so that excess unlocks do not break everything */
   break;
 default:
   return EINVAL;
 }
 // 取出一个被阻塞的线程(如果有的话),唤醒他
 th = dequeue(&mutex->m_waiting);
 release(&mutex->m_spinlock);
 if (th != NULL) restart(th);
 return 0;
}
weak_alias (__pthread_mutex_unlock, pthread_mutex_unlock)

int __pthread_mutexattr_init(pthread_mutexattr_t *attr)
{
 attr->mutexkind = PTHREAD_MUTEX_FAST_NP;
 return 0;
}
weak_alias (__pthread_mutexattr_init, pthread_mutexattr_init)

int __pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
{
 return 0;
}
weak_alias (__pthread_mutexattr_destroy, pthread_mutexattr_destroy)

int __pthread_mutexattr_setkind_np(pthread_mutexattr_t *attr, int kind)
{
 if (kind != PTHREAD_MUTEX_FAST_NP && kind != PTHREAD_MUTEX_RECURSIVE_NP)
   return EINVAL;
 attr->mutexkind = kind;
 return 0;
}
weak_alias (__pthread_mutexattr_setkind_np, pthread_mutexattr_setkind_np)

int __pthread_mutexattr_getkind_np(const pthread_mutexattr_t *attr, int *kind)
{
 *kind = attr->mutexkind;
 return 0;
}
weak_alias (__pthread_mutexattr_getkind_np, pthread_mutexattr_getkind_np)
// 保存init_routine只执行一次
int pthread_once(pthread_once_t * once_control, void (*init_routine)(void))
{
 if (testandset(once_control) == 0) init_routine();
 return 0;
}  

上述内容就是怎么进行基于linuxthreads2.0.1线程源码分析mutex.c,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注创新互联行业资讯频道。

网页名称:怎么进行基于linuxthreads2.0.1线程源码分析mutex.c
链接地址:https://www.cdcxhl.com/article46/pecphg.html

成都网站建设公司_创新互联,为您提供手机网站建设微信公众号自适应网站网站收录服务器托管定制网站

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

网站优化排名