很久以前写的一个功能,当时需要一个优先级的队列,特用新学的swoole写了一个简单的demo,仅满足当时的需求。

功能说明:

完全参考httpsqs增加优先级参数level

用到的工具:

PHP PHP的swoole扩展

思路:

使用swoole扩展监听端口,接收用户传入的参数;用全局变量$info存储所有队列名、每个队列的状态信息(所有优先级、每个优先级中已读数据个数,未读数据个数)等;设置定时器,定时将info写入文件;实际数据存入文件,每个数据占一行,使用fgets按行读出;全局变量$fp保存所有打开的文件句柄,减少文件的打开次数;

优势:

使用世界上最好的语言PHP开发!

性能测试:

1:写性能:

ab -c 100 -n 10000 http://192.168.8.18:5555/?name=test\&opt=put\&data=testdata\&level=3

2:读性能

ab -c 100 -n 10000 http://192.168.8.18:5555/?name=test\&opt=get

附:基础代码

//带优化级的http队列服务

error_reporting(E_ERROR | E_WARNING | E_PARSE);

date_default_timezone_set(‘PRC‘);

$dirname = "./data/queue_"; //文件存储位置及文件名

$infodirname = "./data/info"; //存储基本信息的文件

$maxfilesize = 1024 * 1024 * 1024;//文件最大1G

$fp = array(); //打开文件的句柄

$info = array(); //存储各个队列的基本信息,get/put的位置

$infoflag = 0; //标记info是否被修改过

$tmp = file_get_contents($infodirname);//初始化,从文件中载入基本信息

!empty($tmp) && $info = unserialize($tmp);

$http = new swoole_http_server("0.0.0.0", 5555);

$http->set(array(

‘worker_num‘ => 1, //工作进程数量

));

$http->on(‘WorkerStart‘, function($http) {

$http->addtimer(10000);//增加定时器

});

$http->on(‘Timer‘, ‘cronWriteInfo‘); //定时将基本信息写入文件

$http->on(‘request‘, "mycallback");

$http->start();

function cronWriteInfo() { //定时写文件

global $info,$infoflag,$infodirname;

if($infoflag) { //info被修改过时,才将之写入文件

file_put_contents($infodirname, serialize($info));

}

}

function mycallback($request, $response) {

global $info, $infoflag;

if($request->server[‘request_uri‘] == "/favicon.ico") { //过滤掉浏览器的icon请求

$response->end(" \n");

return ‘‘;

}

$infoflag = 1;

$param = $request->get;

if(empty($param[‘name‘])) {//队列名字不能为空

$ret = "QUEUE_ERROR_QUEUENAME_EMPTY";

} else {

switch ($param[‘opt‘]) {

case ‘get‘:

$ret = get($param[‘name‘]);

break;

case ‘put‘:

if(($data = $param[‘data‘]) && !empty($param[‘data‘])) {

empty($param[‘level‘]) && $param[‘level‘] = 0;

$ret = put($param[‘name‘], $param[‘data‘], $param[‘level‘]);

} else {

$ret = "QUEUE_PUT_ERROR";

}

break;

case ‘status‘:

$ret = json_encode($info);

break;

default:

$ret = "QUEUE_ERROR_PARAM";

break;

}

}

$response->end($ret."\n");

}

function get($queuename) {

global $info;

if($info[$queuename][‘unread‘] > 0) {

$maxlevel = $info[$queuename][‘curMaxlevel‘]; //当前最大优化级

$pos = $info[$queuename][‘leveldata‘][$maxlevel][‘getpos‘]; //文件偏移量

$data = getdataFromFile($queuename, $maxlevel, $pos); //读取数据

$ret = pack("H*", $data); //data是压缩的数据,需要解压

//修改全局变量

$info[$queuename][‘get‘]++;

$info[$queuename][‘unread‘]--;

$info[$queuename][‘leveldata‘][$maxlevel][‘unread‘]--;

if($ret == "QUEUE_END") { //读到的数据不全,原因:数据文件大小超过最大值设置;

$data = getdataFromFile($queuename, $maxlevel, 0); //从头再读一次

$ret = pack("H*", $data); //data是压缩的数据,需要解压

$info[$queuename][‘leveldata‘][$maxlevel][‘get‘] = 1;//读取位置设为1

$info[$queuename][‘leveldata‘][$maxlevel][‘getpos‘] = strlen($data) + 1;

} else {

$info[$queuename][‘leveldata‘][$maxlevel][‘get‘]++;

$info[$queuename][‘leveldata‘][$maxlevel][‘getpos‘] += strlen($data) + 1 ;

}

if($info[$queuename][‘leveldata‘][$maxlevel][‘get‘] == $info[$queuename][‘leveldata‘][$maxlevel][‘put‘]) { //数据读取完毕,重新计算当前最高优先级的数据

$info[$queuename][‘curMaxlevel‘] = getcurMaxlevel($info[$queuename][‘leveldata‘]);

}

return $ret;

} else {

return ‘QUEUE_EMPTY‘;

}

}

function put($queuename, $userdata, $level) {

global $info;

if($info[$queuename][‘leveldata‘][$level][‘put‘]+1 == $info[$queuename][‘leveldata‘][$level][‘get‘]) { //队列写满

return "QUEUE_FULL";

}

$info[$queuename][‘put‘]++;

$info[$queuename][‘unread‘]++;

$newpos = setDataToFile($queuename, $level, $userdata);

$info[$queuename][‘leveldata‘][$level][‘put‘]++;

$info[$queuename][‘leveldata‘][$level][‘unread‘]++;

$info[$queuename][‘leveldata‘][$level][‘putpos‘] = $newpos;

$info[$queuename][‘curMaxlevel‘] = getcurMaxlevel($info[$queuename][‘leveldata‘]);

return "QUEUE_PUT_OK";

}

//获取当前需要执行的优先级最高的数据

function getcurMaxlevel($leveldata) {

krsort($leveldata);

foreach($leveldata as $level => $info) {

if($info[‘unread‘] > 0) {

return $level;

}

}

return 0;

}

//写数据到文件,如果文件写满,循环写入;

function setDataToFile($queuename, $level, $userdata) {

global $dirname, $maxfilesize, $fp;

$file = $dirname.$queuename.$level;

$packdata = unpack("H*", $userdata);

//$$packdata[‘1‘] = $userdata;

$data = $packdata[‘1‘]."\n";

$size = filesize($file);

if(!$fp[$queuename][$level]) {

$fp = fopen($file, "ab+");

}

fseek($fp, $size);

fwrite($fp, $data);

clearstatcache();

if($size + strlen($data) + 1 > $maxfilesize) { //超出文件最大值,进入下一轮

fseek($fp, $size); //倒回指针

fwrite($fp, "QUEUE_END"); //写入标记符号

fseek($fp,0);//重头写

fwrite($fp, $data);

return strlen($data);

} else {

return $size + strlen($data);

}

}

//从文件中读取数据

function getdataFromFile($queuename, $level, $pos) {

global $dirname,$fp;

if(!isset($fp[$queuename][$level])) {

$file = $dirname.$queuename.$level;

$fp = fopen($file, "ab+");

}

fseek($fp, intval($pos));

return trim(fgets($fp));

}

原文:http://www.cnblogs.com/dormscript/p/4787631.html

优先级队列实现php,带优先级的队列 - PHP实现相关推荐

  1. 并发队列-无界阻塞优先级队列

    PriorityBlockingQueue原理探究 一. 前言 PriorityBlockingQueue是带优先级的无界阻塞队列,每次出队都返回优先级最高的元素,是二叉树最小堆的实现,研究过数组方式 ...

  2. 【C++ 语言】容器 ( queue 队列 | stack 栈 | priority_queue 优先级队列 | set 集合 | 容器遍历 | map )

    文章目录 queue 队列 stack 栈 priority_queue 优先级队列 priority_queue 优先级队列指定排序方法 priority_queue 优先级队列排序行为 prior ...

  3. c语言中优先级队列_C ++中的优先级队列

    c语言中优先级队列 A Priority Queue is a variant of a Queue such that it's elements are ordered based on thei ...

  4. *【ZOJ - 3703】Happy Programming Contest(带优先级的01背包)

    题干: In Zhejiang University Programming Contest, a team is called "couple team" if it consi ...

  5. 一文带你认识队列数据结构

    摘要:对于队列来说数据结构相比栈复杂一些,但是也不是很难,搞懂先进先出然后用数组或者链表实现即可. 本文分享自华为云社区<手写各种队列,一文搞定>,原文作者:bigsai  . 前言 栈和 ...

  6. 杨辉三角c语言程序jian,杨辉三角C语言程序队列实现(带源码+解析)

    杨辉三角,即如下 通过学习数据结构,解决杨辉三角,可以使用循环来实现:在循环队列中依次存放第 i-1 行上的元素,然后逐个出队并打印,同时生成第 i 行上的元素并入队. 如果要求计算并输出杨辉三角前 ...

  7. 【队列源码研究】消息队列beanstalkd源码详解

    顺风车运营研发团队 李乐 1.消息队列简介 计算机软件发展的一个重要目标是降低软件耦合性: 网站架构中,系统解耦合的重要手段就是异步,业务之间的消息传递不是同步调用,而是将一个业务操作分为多个阶段,每 ...

  8. 数据结构之栈和队列以及如何封装栈和队列,栈和队列的实例(进制转换和击鼓传花)

    什么是数据结构? 不同的书对数据结构有不同的定义,例如: "数据结构是数据对象,以及存在于该对象的实例和 组成实例的数据元素之间的各种联系.这些联系可以通过定义相关的函数来给出." ...

  9. 多级队列调度算法可视化界面_多级反馈队列调度算法、各种调度算法小结等

    下面我们首先介绍,多级反馈队列调度算法 然后对前面介绍的各种调度算法进行比较 之后呢,我们简单讨论一下 在设计多处理器调度算法时所要考虑的几个问题 多级反馈队列调度算法 是 UNIX 的一个分支,BS ...

最新文章

  1. 开源引领的万亿级市场,该如何打造出成功的商业模式?
  2. 利用正高Dolphin智能广告监测系统做好违法广告监测
  3. php之防注入程序绕过浅谈
  4. python程序员工资-被Python程序员高工资惊到!报告却显示Python热度降了?
  5. Caused by: java.lang.ClassNotFoundException: Didn’t find class on path apk Android Studio解决方案
  6. Web压力测试和手机App测试
  7. FastDFS详细安装步骤,测试;Nginx中配置FastDFS,并提供优化,下载方法,楼主已测
  8. java基础案例7-4升级日记本
  9. AndroidOTA增量包(差分包)制作记录
  10. phpnow开启mysqli扩展
  11. 来自华为创始人演讲的几点感悟,助你新的一年升职加薪
  12. 港股通不得不了解的汇率问题
  13. 百度网盘电脑端看视频声音巨小的解决办法(windows10)
  14. 全球及中国芯片产业研发方向与投资规模预测报告2022版
  15. java中的IO流(超全)(超详解)结合实例轻松掌握
  16. 75 [backtrader期货策略]十大经典策略-分时均线交叉策略
  17. oracle安装文件拒绝访问,oracle数据库的listener.ora文件拒绝访问,求解决!!!
  18. 数学符号的英文表达(持续更新中)
  19. 20145212 罗天晨 网络欺诈技术防范
  20. vue-happy-scroll实现上拉加载更多(vue)

热门文章

  1. RMQ(求区间最值问题)
  2. js 指定年月获取最后天
  3. mysql数据库主从不同步_MySQL数据库之mysql主从数据库不同步的2种解决方法
  4. thymeleaf引用html_SpringBoot+Thymeleaf实现html文件引入(类似include功能)_html/css_WEB-ITnose...
  5. SpringMVC(入门案例)
  6. 计算机不能直接执行c语言编写的源程序,计算机不能直接执行用C语言编写的源程序。...
  7. java中math的方法_Java Math所有方法
  8. redis-cli 链接redis命令
  9. Java数组去重的方法
  10. Kotlin入门(23)适配器的进阶表达