swoole_process源码分析之pop队列

用于从队列中读取消息,其调用如下:

string swoole_process->pop(int $maxsize = 8192);

下面我们分析下其流程。

static PHP_METHOD(swoole_process, pop)
{
    long maxsize = SW_MSGMAX;
    
    //解析输入参数,输入参数就一个maxsize,表示要读取的最大消息长度,默认为8192byte
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &maxsize) == FAILURE)
    {
        RETURN_FALSE;
    }

    if (maxsize > SW_MSGMAX || maxsize <= 0)//参数有效性检查
    {
        maxsize = SW_MSGMAX;
    }

    swWorker *process = swoole_get_object(getThis());//读取内部封装对象swWorker信息
    if (!process->queue)//队列未初始化
    {
        swoole_php_fatal_error(E_WARNING, "no msgqueue, can not use pop()");
        RETURN_FALSE;
    }

    struct
    {
        long type;
        char data[SW_MSGMAX];
    } message;

    if (process->ipc_mode == 2)//按官方文档定义,ipc_mode为2时,表示争抢模式,即所有进程可以从队列里读取数据
    {
        message.type = 0;
    }
    else//非争抢模式,和进程关联
    {
        message.type = process->id;
    }
    
    //从队列中读取数据
    int n = swMsgQueue_pop(process->queue, (swQueue_data *) &message, maxsize);
    if (n < 0)
    {
        RETURN_FALSE;
    }
    SW_RETURN_STRINGL(message.data, n, 1);//组织成字符串返回
}
int swMsgQueue_pop(swMsgQueue *q, swQueue_data *data, int length)
{
    int ret = msgrcv(q->msg_id, data, length, data->mtype, q->flags);//通过linux系统调用读取消息
    if (ret < 0)//读取失败
    {
        SwooleG.error = errno;
        if (errno != ENOMSG && errno != EINTR)//不是被信号中断和阻塞情况下无消息可读
        {
            swSysError("msgrcv(%d, %d, %ld) failed.", q->msg_id, length, data->mtype);//打印错误信息
        }
    }
    return ret;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值