swoole增加了锁的机制,来看看是如何实现的吧

2019年6月24日 375点热度 0人点赞 0条评论

图片

文章来自:CSDN
链接:
https://blog.csdn.net/lcli2009/article/details/82937443
作者:云焰

商务合作:请加微信(QQ):2230304070










































图片

视频教程分享

图片

视频教程有很多,基础的,进阶的,实战的,有查看文章的都会知道,我都会在这里带上一些视频教程。有需要的可以获取,我还是希望你获取的视频教程不是用来收藏的,而是用来计划学习的。

用公众号每天来阅读文章,学习,目前是最方便的。这是自闲暇的时间里,利用5分钟读读技术文章,丰富自己的知识。。。当然,学习有很多种方法,不单单是基于公众号来学习,你可以到网上查找更多的教程,学习文档,技术书本,视频教程!各有各的爱好吧!

今天分享的视频教程

Restful接口开发实战教程(18集)

链接:http://blog.startphp.cn/thread-57-1-1.html


码农程序视频学习与交流:http://blog.startphp.cn

最近整合了一个视频学习网站:码农程序社区与交流,还有很大的改善空间,望有些高人来指点,论自己注册一个账号,以后你们可以自己发帖子了,有问题的也可以抛出来一起交流与学习。小编会把收藏的web视频教程都放在这个网站里,这里有直接获取的视频教程,有需要关注公众号后获取的视频教程,也有一些高质量需要付费的视频教程。我都会慢慢的整理。视频教程以链接+提取码的形式,有需要的欢迎!

视频教程网址:http://blog.startphp.cn

博客地址http://www.startphp.cn







图片

文章正文

图片

锁,这个词我们并不陌生,主要的应用场景会发生在高并发下进行锁。今天的这篇文章咱们主要来讲解一下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(lock1);//创建锁对象,类型为读写锁
        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(lock1);//创建锁对象,类型为乐观锁
        break;
#endif
    case SW_MUTEX:
    default:
        ret = swMutex_create(lock1);//创建锁对象,类型为互斥量
        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 *lockint use_in_process)
{
    int ret;
    bzero(locksizeof(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 *lockint fd)
{
    bzero(locksizeof(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 *lockint use_in_process)
{
    int ret;
    bzero(locksizeof(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 *lockint use_in_process)
{
    int ret;
    bzero(locksizeof(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;
}

以上是文章全部内容,有学习与经验交流的友友可以加小编为好友。以下是码农程序视频分享网的二维码,有需要学习教程,学习视频的请加以下二维码,获取更多视频教程


让学习成为一种习惯


码农程序视频分享网

长按二维码加好友 

图片

学习  |  交流  |  分享  |  文章

36100swoole增加了锁的机制,来看看是如何实现的吧

这个人很懒,什么都没留下

文章评论