| pthread_mutex_unlock.c int internal_function attribute_hidden __pthread_mutex_unlock_usercnt (mutex, decr)  pthread_mutex_t *mutex;  int decr; {  if (__builtin_expect (type, PTHREAD_MUTEX_TIMED_NP)  == PTHREAD_MUTEX_TIMED_NP)  {  /* Always reset the owner field. */  normal:  mutex->__data.__owner = 0;  if (decr)  /* One less user. */  --mutex->__data.__nusers;  /* Unlock. */  lll_unlock (mutex->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex));  return 0;  }  } 
 pthread_mutex_unlock将mutex中的owner清空,并调用了lll_unlock方法 lowlevellock.h  #define __lll_unlock(futex, private)   ((void) ({   int *__futex = (futex);   int __val = atomic_exchange_rel (__futex, 0);     if (__builtin_expect (__val > 1, 0))   lll_futex_wake (__futex, 1, private);   })) #define lll_unlock(futex, private) __lll_unlock(&(futex), private) #define lll_futex_wake(ftx, nr, private)  ({   DO_INLINE_SYSCALL(futex, 3, (long) (ftx),   __lll_private_flag (FUTEX_WAKE, private),   (int) (nr));   _r10 == -1 ? -_retval : _retval;  }) 
 lll_unlock分为两个步骤: 
    将futex设置为0并拿到设置之前的值(用户态操作)如果futex之前的值>1,代表存在锁冲突,也就是说有线程调用了FUTEX_WAIT在休眠,所以通过调用系统函数FUTEX_WAKE唤醒休眠线程 FUTEX_WAKE在上一篇文章有分析,futex机制的核心是当获得锁时,尝试cas更改一个int型变量(用户态操作),如果integer原始值是0,则修改成功,该线程获得锁,否则就将当期线程放入到  wait queue中,wait queue中的线程不会被系统调度(内核态操作)。 futex变量的值有3种:0代表当前锁空闲,1代表有线程持有当前锁,2代表存在锁冲突。futex的值初始化时是0;当调用try_lock的时候会利用cas操作改为1(见上面的trylock函数);当调用lll_lock时,如果不存在锁冲突,则将其改为1,否则改为2。 #define __lll_lock(futex, private)   ((void) ({   int *__futex = (futex);   if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex,   1, 0), 0))   {   if (__builtin_constant_p (private) && (private) == LLL_PRIVATE)   __lll_lock_wait_private (__futex);   else   __lll_lock_wait (__futex, private);   }   })) #define lll_lock(futex, private) __lll_lock (&(futex), private) void __lll_lock_wait_private (int *futex) { //第一次进来的时候futex==1,所以不会走这个if  if (*futex == 2)  lll_futex_wait (futex, 2, LLL_PRIVATE); //在这里会把futex设置成2,并调用futex_wait让当前线程等待  while (atomic_exchange_acq (futex, 2) != 0)  lll_futex_wait (futex, 2, LLL_PRIVATE); } 
 pthread_cond_timedwait (编辑:宣城站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |