swoole加密php教程,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时必须传入,指定文件锁的路径

下面我们介绍下这个锁的实现static PHP_METHOD(swoole_lock, __construct)

{

long type = SW_MUTEX;

char *filelock;

zend_size_t filelock_len = 0;

int ret;

//解析输入参数,这里输入参数有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, "global memory allocation failure.", SW_ERROR_MALLOC_FAIL TSRMLS_CC);

RETURN_FALSE;

}

switch(type)//按type遍历,创建锁对象

{

#ifdef HAVE_RWLOCK

case SW_RWLOCK://如果是读写锁

ret = swRWLock_create(lock, 1);//创建锁对象,类型为读写锁

break;

#endif

case SW_FILELOCK://如果是文件锁

if (filelock_len <= 0)//第二个参数有效性检查

{

zend_throw_exception(swoole_exception_class_entry_ptr, "filelock requires file name of the lock.", SW_ERROR_INVALID_PARAMS TSRMLS_CC);

RETURN_FALSE;

}

int fd;

if ((fd = open(filelock, O_RDWR | O_CREAT, 0666)) < 0) //调用linux函数open,打开文件(不存在则创建)

{

zend_throw_exception_ex(swoole_exception_class_entry_ptr, errno TSRMLS_CC, "open file[%s] failed. Error: %s [%d]", filelock, strerror(errno), errno);

RETURN_FALSE;

}

ret = swFileLock_create(lock, fd);//创建锁对象,类型为文件锁

break;

case SW_SEM:

ret = swSem_create(lock, IPC_PRIVATE);//创建锁对象,类型为信号量

break;

#ifdef HAVE_SPINLOCK

case SW_SPINLOCK:

ret = swSpinLock_create(lock, 1);//创建锁对象,类型为乐观锁

break;

#endif

case SW_MUTEX:

default:

ret = swMutex_create(lock, 1);//创建锁对象,类型为互斥量

break;

}

if (ret < 0)

{

zend_throw_exception(swoole_exception_class_entry_ptr, "failed to create lock.", errno TSRMLS_CC);

RETURN_FALSE;

}

swoole_set_object(getThis(), lock);//PHP侧的对象和swoole内部对象关联

RETURN_TRUE;

}

以下分别介绍下各个不同锁对象的创建过程。

1、读写锁int swRWLock_create(swLock *lock, int use_in_process)

{

int ret;

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函数,锁信息初始化

{

return SW_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;

return SW_OK;

}

2、文件锁。int swFileLock_create(swLock *lock, int fd)

{

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;

return 0;

}

3、信号量锁int swSem_create(swLock *lock, key_t key)

{

int ret;

lock->type = SW_SEM;//设置锁类型为信号量锁

if ((ret = semget(key, 1, IPC_CREAT | 0666)) < 0)//创建信号量,这里设置的属性IPC_CREAT,这表示这种信号量只能用于有亲缘关系的进程间

{

return SW_ERR;

}

if (semctl(ret, 0, SETVAL, 1) == -1)//设置信号量ret的值为1

{

swWarn("semctl(SETVAL) failed");

return SW_ERR;

}

lock->object.sem.semid = ret;//设置信号量ID

/*

* 设置回调函数

*/

lock->lock = swSem_lock;

lock->unlock = swSem_unlock;

lock->free = swSem_free;

return SW_OK;

}

4、乐观锁int swSpinLock_create(swLock *lock, int use_in_process)

{

int ret;

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;

return 0;

}

5、互斥量锁int swMutex_create(swLock *lock, int use_in_process)

{

int ret;

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)

{

return SW_ERR;

}

lock->lock = swMutex_lock;

lock->unlock = swMutex_unlock;

lock->trylock = swMutex_trylock;

lock->free = swMutex_free;

return SW_OK;

}

到此这篇关于swoole锁的机制代码实例讲解的文章就介绍到这了,更多相关swoole锁的机制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值