博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
php socket 模型及效率问题
阅读量:6761 次
发布时间:2019-06-26

本文共 2381 字,大约阅读时间需要 7 分钟。

// 创建套接字socket_create();// 绑定socket_bind();// 监听socket_listen();// 主体, 死循环while(true){  // select模型, 取出可读套接字列表  socket_select();  foreach(sockets) {    // 如果是监听连接请求端口的套接字    if(is listensocket) {      // 接受请求      socket_accept();    }    else {      // 读取封包      socket­_recv();      // 处理用户动作 {问题就在这}      process();    }  }}
php socket 模型及效率问题呼呼安3 票 呼呼安 70// 创建套接字socket_create();// 绑定socket_bind();// 监听socket_listen();// 主体, 死循环while(true){  // select模型, 取出可读套接字列表  socket_select();  foreach(sockets) {    // 如果是监听连接请求端口的套接字    if(is listensocket) {      // 接受请求      socket_accept();    }    else {      // 读取封包      socket­_recv();      // 处理用户动作 {问题就在这}      process();    }  }}关于php做服务端的效率, 我想这里是个问题吧。在每处理一个用户的动作的时候, 整个循环被阻塞在这里, 导致其他的连接不能接受, 其他用户的动作请求不能被处理。 直到process()函数返回才能处理下一个动作。处理一个用户动作的时候, 可能还要涉及到数据库访问等, 可能比较耗时。不知道有没有哪位大仙有解决办法呢。我想的是, 如果能做一个动作队列, 这里的循环只负责接收数据, 然后把数据包保存在一个队列里, 就去接收下一个用户的封包。另一个线程(不知道PHP怎么实现线程, 或是能不能实现)从队列中抽取每一个用户的动作请求来处理它。。或着process()函数能不能做成非阻塞的, 让它可以立即返回。。小弟初学,如有可笑之处,请见谅!评论 (0) • 分享 • 链接 • 2012-07-24 4个答案 票 数  冯义军1 票冯义军14.02K最佳答案这个问题我也遇到过到,比如打开两个终端,telnet socket服务端,如果其中一个不返回,另一个终端总是等待。最后使用fork子进程方式解决,大概代码如下,你可以参考下:死循环部分do {            $msgsock = socket_accept($socket);            $pid = pcntl_fork();            if($pid == -1) {                // fork error ;            }else if($pid) {                socket_close($msgsock);            }else {                $buf = socket_read($msgsock,1024,PHP_NORMAL_READ);                $ret = func($buf); //调用函数处理接收到的内容                socket_write($msgsock,$ret,strlen($ret));                socket_close($msgsock);                //posix_kill(posix_getpid(),0);                exit();            }        }while(true)评论 (10) • 链接 • 2012-07-250@冯义军 你好, 我在本地测试的时候, 可以用cmd运行php, 或是在网页上访问一下, 然后关闭网页就行了, php会一直执行, 然后端口就可以一直访问。。但是我放服务器上(linux), 怎么让它一直执行啊, 我用网页访问它的时候可以连接, 如果关了网页, 就会关闭。 – 呼呼安 2012-07-280@呼呼安 在 socket服务端程序中 开头增加 ignore_user_abort(1); set_time_limit(0); 这两句,就可以运行一次关浏览器了。另外还可以在命令行运行,如 /usr/local/php/bin xxx.php & – 冯义军 2012-07-280@冯义军 set_time_limit(0)这个我加了, ignore_user_abort(1);这个没加就不行吗 – 呼呼安 2012-07-300@呼呼安 ignore_user_abort();主要是设置与客户机断开是否会终止脚本的行,set_time_limit() 主要是指定程序运行的最大时间。 – 冯义军 2012-08-02显示更多隐藏的评论呼呼安2 票呼呼安70我貌似自己想到了一个办法。。process()的地方修改一下, 直接写到数据库里(或着谁有更快的方法请告知)。就是我所说的“动作队列”。再写一个类似的php文件, 也是死循环。 while(true) {// 从数据库里取出一条待处理动作// 处理它// 从数据库里删除该动作}甚至可以多运行几次这个文件, 就是不知道想停的时候怎么停 >_

 

转载地址:http://chfeo.baihongyu.com/

你可能感兴趣的文章
uva 10003 Cutting Sticks 【区间dp】
查看>>
Linux定时器工具-crontab 各參数具体解释及怎样查看日志记录
查看>>
STM32_杂_01_串口代码
查看>>
v4l2驱动文档之——streaming IO【转】
查看>>
Hadoop问题记录:Wrong FS: hdfs://hp5-249:9000/, expected: file:///
查看>>
mfc 链接 access 2007 数据库
查看>>
ImageLoader must be init with configuration before using
查看>>
spring boot Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration
查看>>
@Override用在哪儿
查看>>
小议C#错误调试和异常处理
查看>>
Python基础--webbrowser
查看>>
Dynamics CRM Form表单中通过javascript抓取触发change事件字段的属性名
查看>>
多维透视表 - 矩表实现商品销售对比统计
查看>>
ssh命令、ping命令、traceroute 命令所使用的协议
查看>>
云舒网络译:Rancher1.0正式版公布
查看>>
转 MySQL中的共享锁与排他锁
查看>>
入门--JTBC系统学习(1)
查看>>
我的Android进阶之旅------>怎样解决Android 5.0中出现的警告: Service Intent must be explicit:...
查看>>
单点登录实现机制:桌面sso
查看>>
JVM垃圾回收机制
查看>>