POSIX设置锁的属性

经过网上各种找,自己的各种尝试,终于搞清楚了设置线程锁属性的方法,以前用的mutex的attr都是采用的默认的,从来没有设置过,因为后续开发的需要,所以需要对其进行具体属性的设置,这里详细写一下这个设置的整个过程。

  • 定义锁

pthread_mutex_t lock;

  • 定义mutexattr_t变量

pthread_mutexattr_t attr;

  • 设置mutexattr属性

pthread_mutexattr_init(&attr); // 初始化attr为默认属性
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_TIMED_NP); // 设置attr属性为PTHREAD_MUTEX_TIMED_NP,即默认属性(当一个线程加锁后,其余请求锁的线程形成等待队列,在解锁后按优先级获得锁)

  • 其他相关属性

enum lock_type    // 使用pthread_mutexattr_settype来更改  
{  
        PTHREAD_MUTEX_TIMED_NP [default]//当一个线程加锁后,其余请求锁的线程形成等待队列,在解锁后按优先级获得锁。  
        PTHREAD_MUTEX_ADAPTIVE_NP       // 动作最简单的锁类型,解锁后所有线程重新竞争。  
        PTHREAD_MUTEX_RECURSIVE_NP      // 允许同一线程对同一锁成功获得多次。当然也要解锁多次。其余线程在解锁时重新竞争。  
        PTHREAD_MUTEX_ERRORCHECK_NP     // 若同一线程请求同一锁,返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP动作相同。 此处特别注意linux和windows下的errno.h中的EDEADLK对应的宏的值有差别:linux下为35,windows下36 
} type;  

  • linux下pthread.h中的线程属性

/* Mutex types.  */
enum
{
  PTHREAD_MUTEX_TIMED_NP,
  PTHREAD_MUTEX_RECURSIVE_NP,
  PTHREAD_MUTEX_ERRORCHECK_NP,
  PTHREAD_MUTEX_ADAPTIVE_NP
#ifdef __USE_UNIX98
  ,
  PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_TIMED_NP,
  PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
  PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
  PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
#endif
#ifdef __USE_GNU
  /* For compatibility.  */
  , PTHREAD_MUTEX_FAST_NP = PTHREAD_MUTEX_TIMED_NP
#endif
};

  • 互斥锁属性

       互斥锁的属性在创建锁的时候指定,在LinuxThreads实现中仅有一个锁类型属性,不同的锁类型在试图对一个已经被锁定的互斥锁加锁时表现不同。当前(glibc2.2.3,linuxthreads0.9)有四个值可供选择:

       * PTHREAD_MUTEX_TIMED_NP,这是缺省值,也就是普通锁。当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后按优先级获得锁。这种锁策略保证了资源分配的公平性。

       * PTHREAD_MUTEX_RECURSIVE_NP,嵌套锁,允许同一个线程对同一个锁成功获得多次,并通过多次unlock解锁。如果是不同线程请求,则在加锁线程解锁时重新竞争。

       * PTHREAD_MUTEX_ERRORCHECK_NP,检错锁,如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁。

       * PTHREAD_MUTEX_ADAPTIVE_NP,适应锁,动作最简单的锁类型,仅等待解锁后重新竞争。


  • lock相关函数描述

函数名

pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock - lock and unlock a mutex

概要

#include <pthread.h>

int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);

描述

pthread_mutex_lock() 函数锁住由mutex 指定的mutex 对象。如果mutex 已经被锁住,调用这个函数的线程阻塞直到mutex 可用为止。这跟函数返回的时候参数mutex 指定的mutex 对象变成锁住状态,同时该函数的调用线程成为该mutex 对象的拥有者。
如果mutex 对象的type PTHREAD_MUTEX_NORMAL ,不进行deadlock detection( 死锁检测) 。企图进行relock 这个mutex 会导致deadlock. 如果一个线程对未加锁的或已经unlock mutex 对象进行unlock 操作,结果是不未知的。
如果mutex 类型是PTHREAD_MUTEX_ERRORCHECK ,那么将进行错误检查。如果一个线程企图对一个已经锁住的mutex 进行relock ,将返回一个错误。如果一个线程对未加锁的或已经unlock mutex 对象进行unlock 操作,将返回一个错误。
如果mutex 类型是PTHREAD_MUTEX_RECURSIVE mutex 会有一个锁住次数(lock count )的概念。当一个线程成功地第一次锁住一个mutex 的时候,锁住次数(lock count )被设置为1 ,每一次一个线程unlock 这个mutex 的时候,锁住次数(lock count )就减1 。当锁住次数(lock count )减少为0 的时候,其他线程就能获得该mutex 锁了。如果一个线程对未加锁的或已经unlock mutex 对象进行unlock 操作,将返回一个错误。
如果mutex 类型是PTHREAD_MUTEX_DEFAULT ,企图递归的获取这个mutex 的锁的结果是不确定的。unlock 一个不是被调用线程锁住的mutex 的结果也是不确定的。企图unlock 一个未被锁住的mutex 导致不确定的结果。
pthread_mutex_trylock() 调用在参数 mutex 指定的 mutex 对象当前被锁住的时候立即返回,除此之外, pthread_mutex_trylock() pthread_mutex_lock() 功能完全一样。
The pthread_mutex_unlock() 函数释放有参数 mutex 指定的 mutex 对象的锁。如果被释放取决于该 Mutex 对象的类型属性。如果有多个线程为了获得该 mutex 锁阻塞,调用 pthread_mutex_unlock() 将是该 mutex 可用,一定的调度策略将被用来决定哪个线程可以获得该 mutex 锁。(在 mutex 类型为 PTHREAD_MUTEX_RECURSIVE 的情况下,只有当 lock count 减为 0 并且调用线程在该 mutex 上已经没有锁的时候)(翻译到这里,才觉得我的这个锁概念是多么模糊)
如果一个线程在等待一个mutex 锁得时候收到了一个signal, 那么在从signal handler 返回的时候,该线程继续等待该mutex 锁,就像这个线程没有被中断一样。
返回值
成功, pthread_mutex_lock() pthread_mutex_unlock() 返回0 ,否则返回一个错误的提示码
pthread_mutex_trylock() 在成功获得了一个mutex 的锁后返回0 ,否则返回一个错误提示码

错误

pthread_mutex_lock() pthread_mutex_unlock() 失败的时候
[EINVAL]
mutex 在生成的时候,它的protocol 属性的值是PTHREAD_PRIO_PROTECT ,同时调用线程的优先级(priority) 比该mutex 的当前prority 上限高
pthread_mutex_trylock() 函数在一下情况会失败:
[EBUSY]
The mutex could not be acquired because it was already locked.
mutex 已经被锁住的时候无法再获取锁
The pthread_mutex_lock(), pthread_mutex_trylock() and pthread_mutex_unlock() functions may fail if:
[EINVAL]
mutex 指向的mutex 未被初始化
[EAGAIN]
Mutex lock count( 锁数量) 已经超过 递归索的最大值,无法再获得该mutex
pthread_mutex_lock() 函数在一下情况下会失败:
[EDEADLK]
当前线程已经获得该mutex
pthread_mutex_unlock() 函数在以下情况下会失败:
[EPERM]
当前线程不是该mutex 锁的拥有者
所有的这些函数的错误返回值都不会是[EINTR]





  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值