swoole锁的机制代码实例讲解
发布:smiling 来源: PHP粉丝网 添加日期:2022-04-16 13:17:00 浏览: 评论:0
这篇文章主要介绍了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;
- }
Tags: swoole锁机制
- 上一篇:PHP实现chrome表单请求数据转换为接口使用的json数据
- 下一篇:最后一页
推荐文章
热门文章
最新评论文章
- 写给考虑创业的年轻程序员(10)
- PHP新手上路(一)(7)
- 惹恼程序员的十件事(5)
- PHP邮件发送例子,已测试成功(5)
- 致初学者:PHP比ASP优秀的七个理由(4)
- PHP会被淘汰吗?(4)
- PHP新手上路(四)(4)
- 如何去学习PHP?(2)
- 简单入门级php分页代码(2)
- php中邮箱email 电话等格式的验证(2)