swoole源码分析之swoole_lock的lockwait操作

swoole_lock的lockwait加锁操作,作用于swoole_lock->lock一致,但lockwait可以设置超时时间。

function swoole_lock->lockwait(float $timeout = 1.0) : bool;
  • $timeout传入超时时间,默认为1秒
  • 在规定的时间内未获得锁,返回false
  • 加锁成功返回true
  • 只有Mutex类型的锁支持lockwait

下面我们分析下其流程。

static PHP_METHOD(swoole_lock, lockwait)
{
    double timeout = 1.0;
    
    //解析输入参数,输入参数为锁等待时间,类型为浮点类型
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &timeout) == FAILURE)
    {
        RETURN_FALSE;
    }

    swLock *lock = swoole_get_object(getThis());//获取swoole内部封装对象
    if (lock->type != SW_MUTEX)//仅支持互斥锁类型
    {
        zend_throw_exception(swoole_exception_class_entry_ptr, "only mutex supports lockwait.", -2 TSRMLS_CC);
        RETURN_FALSE;
    }

    SW_LOCK_CHECK_RETURN(swMutex_lockwait(lock, (int)timeout * 1000));//调用互斥类型的锁等待函数
}

1、互斥锁

#ifdef HAVE_MUTEX_TIMEDLOCK //如果支持pthread的锁等待函数,则用pthread的锁等待函数
int swMutex_lockwait(swLock *lock, int timeout_msec)
{
    struct timespec timeo;
    timeo.tv_sec = timeout_msec / 1000;
    timeo.tv_nsec = (timeout_msec - timeo.tv_sec * 1000) * 1000 * 1000;
    return pthread_mutex_timedlock(&lock->object.mutex._lock, &timeo);
}
#else //如果不支持pthread锁等待函数,则用trylock模拟
int swMutex_lockwait(swLock *lock, int timeout_msec)
{
    int sub = 1;
    int sleep_ms = 1000;

    if (timeout_msec > 100)
    {
        sub = 10;
        sleep_ms = 10000;
    }

    while( timeout_msec > 0)//按时间间隔循环
    {
        if (pthread_mutex_trylock(&lock->object.mutex._lock) == 0)
        {
            return 0;
        }
        else
        {
            usleep(sleep_ms);//让出CPU,防止CPU 100%
            timeout_msec -= sub;
        }
    }
    return ETIMEDOUT;
}
#endif

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值