加载中…
个人资料
行者无疆-超越
行者无疆-超越
  • 博客等级:
  • 博客积分:0
  • 博客访问:23,405
  • 关注人气:1
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
相关博文
推荐博文
正文 字体大小:

Mutex类使用Futex实现同步

(2014-04-24 10:47:36)
标签:

android

futex

it

分类: Android的同步和消息

下面我们将通过一个实际的例子来进一步的了解Futex的用法。前面我们介绍Bionic中的线程管理时介绍了pthread的临界区函数。临界区的实现中最重要的是上锁和解锁函数,下面我们看看它们的实现:

1.        Bionic的实现中,pthread_mutex_lock()调用了内部函数_normal_lock()来实现上锁功能,代码如下:

static __inline__ void _normal_lock(pthread_mutex_t*  mutex, int shared)

{

    const int unlocked = shared | MUTEX_STATE_BITS_UNLOCKED;

const int locked_uncontended = shared | MUTEX_STATE_BITS_LOCKED_UNCONTENDED;

    if (__bionic_cmpxchg(unlocked, locked_uncontended, &mutex->value) != 0) {

        const int locked_contended = shared | MUTEX_STATE_BITS_LOCKED_CONTENDED;

        while (__bionic_swap(locked_contended, &mutex->value) != unlocked)

            __futex_wait_ex(&mutex->value, shared, locked_contended, 0);

    }

    ANDROID_MEMBAR_FULL();

}

_normal_lock()函数调用原子操作函数__bionic_cmpxchg()来检测mutex->value的值是否等于unlocked变量的值(unlocked代表未锁定的状态),如果相等则将mutex->value的值设置为locked_uncontended变量的值(表示锁定但是没有竞争的状态)。__bionic_cmpxchg()函数在mutex->value不等于unlocked的情况下会返回非0,这样就进入if语句内执行。

__bionic_swap()函数会将mutex->value的值设为locked_contended(表示有竞争),同时返回mutex->value原来的值。如果mutex->value原来的值不等于unlocked则调用函数__futex_wait_ex()挂起线程等待。这里使用while循环是因为可能有多个线程在等待,即使从挂起状态恢复后也可能还是抢不到锁,所以要重新进入等待状态。

2.        pthread_mutex_unlock()则调用了内部函数_normal_unlock()来实现解锁功能。代码如下所示:

static __inline__ void _normal_unlock(pthread_mutex_t*  mutex, int shared)

{

    ANDROID_MEMBAR_FULL();

if (__bionic_atomic_dec(&mutex->value) !=

              (shared|MUTEX_STATE_BITS_LOCKED_UNCONTENDED)) {

        mutex->value = shared;

        __futex_wake_ex(&mutex->value, shared, 1);

    }

}

解锁时首先使用__bionic_atomic_dec()函数对mutex->value执行减一操作,函数__bionic_atomic_dec()将返回mutex->value原来的值。如果mutex->value原来的值不是锁定但是无竞争的状态,也就意味着还有线程在等待,所以要调用__futex_wake_ex()来唤醒等待的线程。

Mutex的实现代码中我们应该能体会到Futex的优点,如果多个线程访问临界区的时间是错开的,也就是没有真正的竞争发生,那么实际上是不会产生系统调用的。

当然如果多个线程在竞争临界区的锁,还是一样会有挂起和唤醒的系统调用。这种情况下Futex的效率和以前的实现就没有区别了。

0

阅读 评论 收藏 转载 喜欢 打印举报/Report
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 电话:4000520066 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有