当前位置:首页 > PHP教程 > php高级应用 > 列表

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时必须传入,指定文件锁的路径

下面我们介绍下这个锁的实现

  1. static PHP_METHOD(swoole_lock, __construct) 
  2. { 
  3.     long type = SW_MUTEX; 
  4.     char *filelock; 
  5.     zend_size_t filelock_len = 0; 
  6.     int ret; 
  7.     //解析输入参数,这里输入参数有2个,其中type表示锁的类型,另外个参数是文件锁时必须传入(表示文件锁对应的文件路径),其他锁时,不需要这个参数 
  8.     if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ls", &type, &filelock, &filelock_len) == FAILURE) 
  9.     { 
  10.         RETURN_FALSE; 
  11.     } 
  12.     //从内存池申请锁对象空间,这里仅仅是申请锁空间 
  13.     swLock *lock = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swLock)); 
  14.     if (lock == NULL)//申请空间失败 
  15.     { 
  16.         zend_throw_exception(swoole_exception_class_entry_ptr, "global memory allocation failure.", SW_ERROR_MALLOC_FAIL TSRMLS_CC); 
  17.         RETURN_FALSE; 
  18.     } 
  19.    
  20.     switch(type)//按type遍历,创建锁对象 
  21.     { 
  22. #ifdef HAVE_RWLOCK 
  23.     case SW_RWLOCK://如果是读写锁 
  24.         ret = swRWLock_create(lock, 1);//创建锁对象,类型为读写锁 
  25.         break; 
  26. #endif 
  27.     case SW_FILELOCK://如果是文件锁 
  28.         if (filelock_len <= 0)//第二个参数有效性检查 
  29.         { 
  30.             zend_throw_exception(swoole_exception_class_entry_ptr, "filelock requires file name of the lock.", SW_ERROR_INVALID_PARAMS TSRMLS_CC); 
  31.             RETURN_FALSE; 
  32.         } 
  33.         int fd; 
  34.         if ((fd = open(filelock, O_RDWR | O_CREAT, 0666)) < 0) //调用linux函数open,打开文件(不存在则创建) 
  35.         { 
  36.             zend_throw_exception_ex(swoole_exception_class_entry_ptr, errno TSRMLS_CC, "open file[%s] failed. Error: %s [%d]", filelock, strerror(errno), errno); 
  37.             RETURN_FALSE; 
  38.         } 
  39.         ret = swFileLock_create(lock, fd);//创建锁对象,类型为文件锁 
  40.         break; 
  41.     case SW_SEM: 
  42.         ret = swSem_create(lock, IPC_PRIVATE);//创建锁对象,类型为信号量 
  43.         break; 
  44. #ifdef HAVE_SPINLOCK 
  45.     case SW_SPINLOCK: 
  46.         ret = swSpinLock_create(lock, 1);//创建锁对象,类型为乐观锁 
  47.         break; 
  48. #endif 
  49.     case SW_MUTEX: 
  50.     default: 
  51.         ret = swMutex_create(lock, 1);//创建锁对象,类型为互斥量 
  52.         break; 
  53.     } 
  54.     if (ret < 0) 
  55.     { 
  56.         zend_throw_exception(swoole_exception_class_entry_ptr, "failed to create lock.", errno TSRMLS_CC); 
  57.         RETURN_FALSE; 
  58.     } 
  59.     swoole_set_object(getThis(), lock);//PHP侧的对象和swoole内部对象关联 
  60.     RETURN_TRUE; 
  61. } 

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

1、读写锁

  1. int swRWLock_create(swLock *lock, int use_in_process) 
  2. { 
  3.     int ret; 
  4.     bzero(lock, sizeof(swLock));//锁空间初始化 
  5.     lock->type = SW_RWLOCK;//设置锁的类型为读写锁 
  6.     pthread_rwlockattr_init(&lock->object.rwlock.attr);//linux函数,锁属性信息初始化 
  7.     if (use_in_process == 1)//标记为在进程中使用,这里pthread开头的linux函数默认都是针对线程的 
  8.     { 
  9.         //设置锁的属性信息,标记为在进程中使用 
  10.         pthread_rwlockattr_setpshared(&lock->object.rwlock.attr, PTHREAD_PROCESS_SHARED); 
  11.     } 
  12.    
  13.     if ((ret = pthread_rwlock_init(&lock->object.rwlock._lock, &lock->object.rwlock.attr)) < 0)//linux函数,锁信息初始化 
  14.     { 
  15.         return SW_ERR; 
  16.     } 
  17.    
  18.     /* 
  19.      * 设置锁的回调函数 
  20.      */ 
  21.     lock->lock_rd = swRWLock_lock_rd; 
  22.     lock->lock = swRWLock_lock_rw; 
  23.     lock->unlock = swRWLock_unlock; 
  24.     lock->trylock = swRWLock_trylock_rw; 
  25.     lock->trylock_rd = swRWLock_trylock_rd; 
  26.     lock->free = swRWLock_free; 
  27.     return SW_OK; 
  28. } 

2、文件锁。

  1. int swFileLock_create(swLock *lock, int fd) 
  2. { 
  3.     bzero(lock, sizeof(swLock));//锁对象信息初始化 
  4.     lock->type = SW_FILELOCK;//设置锁的类型为文件锁 
  5.    
  6.     /* 
  7.      * 设置锁的回调函数 
  8.      */ 
  9.     lock->object.filelock.fd = fd; 
  10.     lock->lock_rd = swFileLock_lock_rd; 
  11.     lock->lock = swFileLock_lock_rw; 
  12.     lock->trylock_rd = swFileLock_trylock_rd; 
  13.     lock->trylock = swFileLock_trylock_rw; 
  14.     lock->unlock = swFileLock_unlock; 
  15.     lock->free = swFileLock_free; 
  16.     return 0; 
  17. } 

3、信号量锁

  1. int swSem_create(swLock *lock, key_t key) 
  2. { 
  3.     int ret; 
  4.     lock->type = SW_SEM;//设置锁类型为信号量锁 
  5.     if ((ret = semget(key, 1, IPC_CREAT | 0666)) < 0)//创建信号量,这里设置的属性IPC_CREAT,这表示这种信号量只能用于有亲缘关系的进程间 
  6.     { 
  7.         return SW_ERR; 
  8.     } 
  9.    
  10.     if (semctl(ret, 0, SETVAL, 1) == -1)//设置信号量ret的值为1 
  11.     { 
  12.         swWarn("semctl(SETVAL) failed"); 
  13.         return SW_ERR; 
  14.     } 
  15.     lock->object.sem.semid = ret;//设置信号量ID 
  16.    
  17.     /* 
  18.      * 设置回调函数 
  19.      */ 
  20.     lock->lock = swSem_lock; 
  21.     lock->unlock = swSem_unlock; 
  22.     lock->free = swSem_free; 
  23.    
  24.     return SW_OK; 
  25. } 

4、乐观锁

  1. int swSpinLock_create(swLock *lock, int use_in_process) 
  2. { 
  3.     int ret; 
  4.     bzero(lock, sizeof(swLock));//初始化锁对象 
  5.     lock->type = SW_SPINLOCK;//设置锁的类型为乐观锁 
  6.     //执行锁的初始化操作,这里指明是在多进程中使用 
  7.     if ((ret = pthread_spin_init(&lock->object.spinlock.lock_t, use_in_process)) < 0) 
  8.     { 
  9.         return -1; 
  10.     } 
  11.    
  12.     /* 
  13.      * 设置回调函数信息 
  14.      */ 
  15.     lock->lock = swSpinLock_lock; 
  16.     lock->unlock = swSpinLock_unlock; 
  17.     lock->trylock = swSpinLock_trylock; 
  18.     lock->free = swSpinLock_free; 
  19.     return 0; 
  20. } 

5、互斥量锁

  1. int swMutex_create(swLock *lock, int use_in_process) 
  2. { 
  3.     int ret; 
  4.     bzero(lock, sizeof(swLock)); 
  5.     lock->type = SW_MUTEX; 
  6.     pthread_mutexattr_init(&lock->object.mutex.attr); 
  7.     if (use_in_process == 1) 
  8.     { 
  9.         pthread_mutexattr_setpshared(&lock->object.mutex.attr, PTHREAD_PROCESS_SHARED); 
  10.     } 
  11.     if ((ret = pthread_mutex_init(&lock->object.mutex._lock, &lock->object.mutex.attr)) < 0) 
  12.     { 
  13.         return SW_ERR; 
  14.     } 
  15.     lock->lock = swMutex_lock; 
  16.     lock->unlock = swMutex_unlock; 
  17.     lock->trylock = swMutex_trylock; 
  18.     lock->free = swMutex_free; 
  19.     return SW_OK; 
  20. }

Tags: swoole锁机制

分享到: