swoole锁的机制怎样理解,swoole_lock是如何实现?
导读:这篇文章给大家分享的是swoole锁的相关内容,下文会介绍swoole锁的机制,以及swoole_lock实现,有一定的参考学习价值,因此分享给大家做个参考,文中示例代码介绍的非常详细,感兴趣的朋友接下来一起跟随小编看看吧。 swoole_...
这篇文章给大家分享的是swoole锁的相关内容,下文会介绍swoole锁的机制,以及swoole_lock实现,有一定的参考学习价值,因此分享给大家做个参考,文中示例代码介绍的非常详细,感兴趣的朋友接下来一起跟随小编看看吧。
swoole_lock类支持5种锁的类型:
- 文件锁 SWOOLE_FILELOCK
- 读写锁 SWOOLE_RWLOCK
- 信号量 SWOOLE_SEM
- 互斥锁 SWOOLE_MUTEX
- 自旋锁 SWOOLE_SPINLOCK
创建这些锁的过程其实就是调用构造函数的过程,调用的形式如下:
swoole_lock->
__construct(int $type, [string $lockfile])
$type为锁的类型
$lockfile,当类型为SWOOLE_FILELOCK时必须传入,指定文件锁的路径
下面我们介绍下这个锁的实现
staticPHP_METHOD(swoole_lock,__construct)
{
longtype=SW_MUTEX;
char*filelock;
zend_size_tfilelock_len=0;
intret;
//解析输入参数,这里输入参数有2个,其中type表示锁的类型,另外个参数是文件锁时必须传入(表示文件锁对应的文件路径),//其他锁时,不需要这个参数
if(zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC,"|ls",&
type,&
filelock,&
filelock_len)==FAILURE)
{
RETURN_FALSE;
}
//从内存池申请锁对象空间,这里仅仅是申请锁空间
swLock*lock=SwooleG.memory_pool->
alloc(SwooleG.memory_pool,sizeof(swLock));
if(lock==NULL)//申请空间失败
{
zend_throw_exception(swoole_exception_class_entry_ptr,"globalmemoryallocationfailure.",SW_ERROR_MALLOC_FAILTSRMLS_CC);
RETURN_FALSE;
}
switch(type)//按type遍历,创建锁对象
{
#ifdefHAVE_RWLOCK
caseSW_RWLOCK://如果是读写锁
ret=swRWLock_create(lock,1);
//创建锁对象,类型为读写锁
break;
#endif
caseSW_FILELOCK://如果是文件锁
if(filelock_len=0)//第二个参数有效性检查
{
zend_throw_exception(swoole_exception_class_entry_ptr,"filelockrequiresfilenameofthelock.",SW_ERROR_INVALID_PARAMSTSRMLS_CC);
RETURN_FALSE;
}
intfd;
if((fd=open(filelock,O_RDWR|O_CREAT,0666))0)//调用linux函数open,打开文件(不存在则创建)
{
zend_throw_exception_ex(swoole_exception_class_entry_ptr,errnoTSRMLS_CC,"openfile[%s]failed.Error:%s[%d]",filelock,strerror(errno),errno);
RETURN_FALSE;
}
ret=swFileLock_create(lock,fd);
//创建锁对象,类型为文件锁
break;
caseSW_SEM:
ret=swSem_create(lock,IPC_PRIVATE);
//创建锁对象,类型为信号量
break;
#ifdefHAVE_SPINLOCK
caseSW_SPINLOCK:
ret=swSpinLock_create(lock,1);
//创建锁对象,类型为乐观锁
break;
#endif
caseSW_MUTEX:
default:
ret=swMutex_create(lock,1);
//创建锁对象,类型为互斥量
break;
}
if(ret0)
{
zend_throw_exception(swoole_exception_class_entry_ptr,"failedtocreatelock.",errnoTSRMLS_CC);
RETURN_FALSE;
}
swoole_set_object(getThis(),lock);
//PHP侧的对象和swoole内部对象关联
RETURN_TRUE;
}
以下分别介绍下各个不同锁对象的创建过程。
1、读写锁
intswRWLock_create(swLock*lock,intuse_in_process)
{
intret;
bzero(lock,sizeof(swLock));
//锁空间初始化
lock->
type=SW_RWLOCK;
//设置锁的类型为读写锁
pthread_rwlockattr_init(&
lock->
object.rwlock.attr);
//linux函数,锁属性信息初始化
if(use_in_process==1)//标记为在进程中使用,这里pthread开头的linux函数默认都是针对线程的
{
//设置锁的属性信息,标记为在进程中使用
pthread_rwlockattr_setpshared(&
lock->
object.rwlock.attr,PTHREAD_PROCESS_SHARED);
}
if((ret=pthread_rwlock_init(&
lock->
object.rwlock._lock,&
lock->
object.rwlock.attr))0)//linux函数,锁信息初始化
{
returnSW_ERR;
}
/*
*设置锁的回调函数
*/
lock->
lock_rd=swRWLock_lock_rd;
lock->
lock=swRWLock_lock_rw;
lock->
unlock=swRWLock_unlock;
lock->
trylock=swRWLock_trylock_rw;
lock->
trylock_rd=swRWLock_trylock_rd;
lock->
free=swRWLock_free;
returnSW_OK;
}
2、文件锁。
intswFileLock_create(swLock*lock,intfd)
{
bzero(lock,sizeof(swLock));
//锁对象信息初始化
lock->
type=SW_FILELOCK;
//设置锁的类型为文件锁
/*
*设置锁的回调函数
*/
lock->
object.filelock.fd=fd;
lock->
lock_rd=swFileLock_lock_rd;
lock->
lock=swFileLock_lock_rw;
lock->
trylock_rd=swFileLock_trylock_rd;
lock->
trylock=swFileLock_trylock_rw;
lock->
unlock=swFileLock_unlock;
lock->
free=swFileLock_free;
return0;
}
3、信号量锁
intswSem_create(swLock*lock,key_tkey)
{
intret;
lock->
type=SW_SEM;
//设置锁类型为信号量锁
if((ret=semget(key,1,IPC_CREAT|0666))0)//创建信号量,这里设置的属性IPC_CREAT,这表示这种信号量只能用于有亲缘关系的进程间
{
returnSW_ERR;
}
if(semctl(ret,0,SETVAL,1)==-1)//设置信号量ret的值为1
{
swWarn("semctl(SETVAL)failed");
returnSW_ERR;
}
lock->
object.sem.semid=ret;
//设置信号量ID
/*
*设置回调函数
*/
lock->
lock=swSem_lock;
lock->
unlock=swSem_unlock;
lock->
free=swSem_free;
returnSW_OK;
}
4、乐观锁
intswSpinLock_create(swLock*lock,intuse_in_process)
{
intret;
bzero(lock,sizeof(swLock));
//初始化锁对象
lock->
type=SW_SPINLOCK;
//设置锁的类型为乐观锁
//执行锁的初始化操作,这里指明是在多进程中使用
if((ret=pthread_spin_init(&
lock->
object.spinlock.lock_t,use_in_process))0)
{
return-1;
}
/*
*设置回调函数信息
*/
lock->
lock=swSpinLock_lock;
lock->
unlock=swSpinLock_unlock;
lock->
trylock=swSpinLock_trylock;
lock->
free=swSpinLock_free;
return0;
}
5、互斥量锁
intswMutex_create(swLock*lock,intuse_in_process)
{
intret;
bzero(lock,sizeof(swLock));
lock->
type=SW_MUTEX;
pthread_mutexattr_init(&
lock->
object.mutex.attr);
if(use_in_process==1)
{
pthread_mutexattr_setpshared(&
lock->
object.mutex.attr,PTHREAD_PROCESS_SHARED);
}
if((ret=pthread_mutex_init(&
lock->
object.mutex._lock,&
lock->
object.mutex.attr))0)
{
returnSW_ERR;
}
lock->
lock=swMutex_lock;
lock->
unlock=swMutex_unlock;
lock->
trylock=swMutex_trylock;
lock->
free=swMutex_free;
returnSW_OK;
}
以上就是swoole锁的相关的介绍,上述示例具有一定的借鉴价值,对大家学习和理解swoole锁有一定的帮助,有需要的朋友可以参考学习。最后,想要了解更多可以继续浏览网络其他相关的文章。
文本转载自脚本之家
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: swoole锁的机制怎样理解,swoole_lock是如何实现?
本文地址: https://pptw.com/jishu/653165.html
