首页后端开发PHPswoole锁的机制怎样理解,swoole_lock是如何实现?

swoole锁的机制怎样理解,swoole_lock是如何实现?

时间2024-03-26 01:20:03发布访客分类PHP浏览1163
导读:这篇文章给大家分享的是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
eval是es6中的方法吗,用来做什么的 es6中continue跳过语句怎么用,有什么要注意的

游客 回复需填写必要信息