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