swoole_process源码分析之消息队列创建

swoole_process创建的进程默认在父子进程间通过管道的方式进行进程间通信方式,而swoole_process也提供消息队列的方式进行进程间通信,对外和队列相关的接口有创建队列、push消息、pop消息、stat消息、销毁队列等,我们下面逐步分析。

启用队列的操作如下:

bool swoole_process->useQueue(int $msgkey = 0, int $mode = 2);

下面我们逐步分析下其流程。

static PHP_METHOD(swoole_process, useQueue)
{
    long msgkey = 0;
    long mode = 2;
    
    //解析输入参数
    //msgkey表示消息队列的key,默认会使用ftok(__FILE__, 1)作为KEY
    //通信模式,默认为2,表示争抢模式,所有创建的子进程都会从队列中取数据
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &msgkey, &mode) == FAILURE)
    {
        RETURN_FALSE;
    }
    
    //获取swoole内部封装对象
    swWorker *process = swoole_get_object(getThis());

    if (msgkey <= 0)//未传入msgkey信息
    {
        msgkey = ftok(sw_zend_get_executed_filename(), 1);//通过当前文件作为参数调用ftok生成msgkey
    }

    swMsgQueue *queue = emalloc(sizeof(swMsgQueue));//申请队列空间
    if (swMsgQueue_create(queue, 1, msgkey, 0) < 0)//创建队列,后续展开分析
    {
        RETURN_FALSE;
    }

    if (mode & MSGQUEUE_NOWAIT)//设置队列非阻塞属性
    {
        swMsgQueue_set_blocking(queue, 0);
        mode = mode & (~MSGQUEUE_NOWAIT);
    }

    process->queue = queue;
    process->ipc_mode = mode;
    zend_update_property_long(swoole_process_class_entry_ptr, getThis(), ZEND_STRL("msgQueueId"), queue->msg_id TSRMLS_CC);//更新soole_process的msgQueueId属性
    zend_update_property_long(swoole_process_class_entry_ptr, getThis(), ZEND_STRL("msgQueueKey"), msgkey TSRMLS_CC);//更新soole_process的msgQueueKey属性
    RETURN_TRUE;
}
int swMsgQueue_create(swMsgQueue *q, int blocking, key_t msg_key, int perms)
{
    if (perms <= 0 || perms >= 01000)
    {
        perms = 0666;
    }
    int msg_id;
    msg_id = msgget(msg_key, IPC_CREAT | perms);//调用linux系统调用msgget创建队列,返回队列ID
    if (msg_id < 0)//创建失败
    {
        swSysError("msgget() failed.");
        return SW_ERR;
    }
    else//成功
    {
        bzero(q, sizeof(swMsgQueue));
        q->msg_id = msg_id;
        q->perms = perms;
        q->blocking = blocking;
        swMsgQueue_set_blocking(q, blocking);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值