PHP内核队列使用一例

写了一段代码,展示了PHP如何使用内核队列。

场景是:父进程产生消息,放入队列,子进程从队列读取消息,并处理。

<?php
$msg_key = ftok(__FILE__, 'a');
$msg_queue = msg_get_queue($msg_key, 0644);

/**
 * 父进程往队列发送消息
 * @param $msg_queue
 * @param $child_count
 */
function parent_main($msg_queue, $child_count) {
    // 发送100个消息
    for ($j = 0; $j !== 100; $j++) {
        msg_send($msg_queue, 1, 'hello ' . $j);
    }
    // 等待所有子进程退出
    for ($j = 0; $j !== $child_count; $j++) {
        pcntl_wait($status);
    }
    // 删除队列
    msg_remove_queue($msg_queue);
}

/**
 * 子进程从队列获取消息
 * @param $msg_queue
 */
function child_main($msg_queue) {
    // 刚启动时先睡一会儿,否则会因为读到的是空队列而直接退出
    usleep(100000);
    while (true) {
        $ret = msg_receive($msg_queue, 0, $message_type,
            1024, $message, true, MSG_IPC_NOWAIT);
        // 如果没有消息可读了,就退出
        if (!$ret) {
            break;
        }
        echo 'Child ' . posix_getpid() . ' receive message: ' . $message . PHP_EOL;
    }
}

$child_count = 4;
for ($i = 0; $i !== $child_count; $i++) {
    $pid = pcntl_fork();
    if ($pid === -1) {
        die('Fork error');
    } else if ($pid === 0) {
        child_main($msg_queue);
        exit(0);
    }
}

parent_main($msg_queue, $child_count);

如果在程序退出前忘记删除队列了,可以用 ipcs 命令查看当前系统中的队列:

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
0x6d01e8f6 0          root       666        0            0           
0x6d01e8f5 32769      root       666        0            0           
0x6d01e8f4 65538      root       666        0            0           
0x310164c6 98307      root       644        50           2           

记住 msqid 这一列,这是队列ID,然后用 ipcrm 命令就可以删除不用的队列:

ipcrm -q 队列ID
发布了43 篇原创文章 · 获赞 50 · 访问量 68万+

猜你喜欢

转载自blog.csdn.net/supergao222/article/details/79871675