PHP-Socket-阻塞与非阻塞,同步与异步概念的理解
同步:
对象的阻塞模式和阻塞函数调用
对象是否处于阻塞模式和函数是不是阻塞调用有很强的相关性,但是并不是一一对应的。阻塞对象上可以有非阻塞的调用方式,我们可以通过一定的API去轮询状
2. 异步,就是我调用一个功能,不需要知道该功能结果,该功能有结果后通知我(回调通知)
3. 阻塞,
4. 非阻塞,
异步:请求通过事件触发->服务器处理(这是浏览器仍然可以作其他事情)->处理完毕
阻塞和非阻塞是指当进程访问的数据如果尚未就绪,进程是否需要等待,简单说这相当于函数内部的实现区别,也就是未就绪时是直接返回还是等待就绪;
2)非阻塞I/O (nonblocking I/O)
3) I/O复用(select 和poll) (I/O multiplexing)
4)信号驱动I/O (signal driven I/O (SIGIO))
5)异步I/O (asynchronous I/O (the POSIX aio_functions))
异步IO不会引起进程阻塞。
IO复用是先通过select调用阻塞。
2、效率提升,不是轮询的方式,不会随着FD数目的增加效率下降。只有活跃可用的FD才会调用callback函数;
select
|
单个进程所能打开的最大连接数有FD_SETSIZE宏定 义,其大小是32个整数的大小(在32位的机器上,大小就是32*32,同理64位机器上FD_SETSIZE为32*64),当然我们可以对进行修改, 然后重新编译内核,但是性能可能会受到影响,这需要进一步的测试。
|
poll
|
poll本质上和select没有区别,但是它没有最大连接数的限制,原因是它是基于链表来存储的
|
epoll
|
虽然连接数有上限,但是很大,1G内存的机器上可以打开10万左右的连接,2G内存的机器可以打开20万左右的连接
|
select
|
因为每次调用时都会对连接进行线性遍历,所以随着FD的增加会造成遍历速度慢的“线性下降性能问题”。
|
poll
|
同上
|
epoll
|
因为epoll内核中实现是根据每个fd上的 callback函数来实现的,只有活跃的socket才会主动调用callback,所以在活跃socket较少的情况下,使用epoll没有前面两者 的线性下降的性能问题,但是所有socket都很活跃的情况下,可能会有性能问题。
|
select
|
内核需要将消息传递到用户空间,都需要内核拷贝动作
|
poll
|
同上
|
epoll
|
epoll通过内核和用户空间共享一块内存来实现的。
|
采集的时候有时候需要过滤掉多余的标签属性,比如 img标签过滤掉除了src属性之外的所有属性例如删除titile alt等属性以及一些脚的onclick属性等。
例如过滤除了src之外的所有属性
$str= preg_replace('/\s(?!src)[a-zA-Z]+=[\'\"]{1}[^\'\"]+[\'\"]{1}/iu',' $str);
上面的实例代码是过滤掉除了src属性外的所有标签属性
过滤设置过滤除了alt和src之外的所有属性,代码如下:
$str = preg_replace('/\s(?!(src|alt))[a-zA-Z]+=[^\s]*/iu',' ', $str);
过滤所有html标签的属性的正则表达式:
$str = preg_replace("/<([a-z]+)[^>]*>/i","",$str );
只过滤alt属性的正则表达式:
(\s)alt=[^\s]*
过滤所有html标签的属性的正则表达式
$search = array ("'<script[^>]*?>.*?</script>'si", // 去掉 javascript
"'<[\/\!]*?[^<>]*?>'si", // 去掉 HTML 标记
"'([\r\n])[\s]+'", // 去掉空白字符
"'&(quot|#34);'i", // 替换 HTML 实体
"'&(amp|#38);'i",
"'&(lt|#60);'i",
"'&(gt|#62);'i",
"'&(nbsp|#160);'i"
); // 作为 PHP 代码运行
$replace = array ("","","\\1","\"","&","<",">"," ");
$html = preg_replace($search, $replace, $html);
字节码缓存组件 Zend Optimizer+ 现在更改名字为 Zend opcache了。且在php 5.5版本后,会集成到php的官方组件中,也就没有必要安装其他的APC,eAccelerator等了。。
APC与Opcache都是字节码缓存也就是,PHP在被编译的时候,首先会把php代码转换为字节码,字节码然后被执行。
php文件第二次执行时,同样还是会重新转换为字节码,但是很多时候,文件内容几乎是一样的,比如静态HTML文件,生成后内容许久都不会改变,用户访问请求直接由服务器读取响应给客户端浏览器。都不用经过PHP进行解析构建了。
内存中的字节码数据,可以直接缓存进行二次编译。这样程序就会快一些,cpu的消耗也少了。
详细介绍看这两篇
新一代 PHP 加速插件 Zend Opcache
php的 zend opcache VS apc 性能比较
我主要是用来测试了一下phpcmsV9.5.4 的默认index.php主页,没有数据内容,但有sql查询操作
测试是Apache2.2.6 32Bit 服务器,PHP 5.4.26 ts,mysql 5.6.16 64Bit
ab 版本 This is ApacheBench, Version 2.3 <$Revision: 655654 $>
请求数:1000
并发数:10
没有加载opcache测试
第一次测试
吞吐率有所提高 40.73 rps,耗时 24.554 s,每个请求耗时245.544 ms
opcache配置信息
1 |
opcache.memory_consumption=128 |
2 |
opcache.interned_strings_buffer=8 |
3 |
opcache.max_accelerated_files=4000 |
4 |
opcache.revalidate_freq=60 |
5 |
opcache.fast_shutdown=1 |
6 |
opcache.enable_cli=1 |
例如:
<?php
header('Content-type:text/html; charset=utf-8');
$str = 'abc';
echo $str; // 输出abc
?>
赋予$str 一个新的值
<?php
header('Content-type:text/html; charset=utf-8');
$str = 'new abc';
echo $str; // 输出的还是 abc
?>
这是因为$str 已经被编译为字节码了,再次访问时,内存里面还是可以找到对应的缓存,就没有进行重新编译,返回的值也就还是之前的值 abc
不过,opcache有一个参数可以用来设置缓存时间长度
opcache.force_restart_timeout (default "180")
默认时间为180秒,还是建议本地不用开启opcache
注意:官方给了一个Note,如果opcache要与xdebug同时加载,那么opcache需要在xdebug之前进行加载。
但是我本地测试了一下,xdebug先加载,再加载opcache,也正常启动了,xdebug,opcache都加载成功,opcache缓存也正常。
不过还是按照官方的建议来安装加载,否则可能会出现奇怪的错误吧
DIRECTORY_SEPARATOR是一个显示系统分隔符的命令,DIRECTORY_SEPARATOR是PHP的内部常量,不需要任何定义与包含即可直接使用。
众所周知,在windows下路径分隔符是(当然/在部分系统上也是可以正常运行的),在linux上路径的分隔符是/,这就导致了一个问题,比如开发机器是windows,有一个图片上传程序,调试机器上指定的上传文件保存目录是:define(‘ROOT’, dirname(__FILE__).”upload”),在本地调试都很正常,但是上传到linux服务器的时候会发现会出错。
这个问题就是出在文件的分隔符上,windows上习惯性的使用作为文件分隔符,但是在linux上人家是不认识这个标识的,人家只认识/,于是就要引入下面这个php内置变量了:DIRECTORY_SEPARATOR。
上面的写法可以改写为以下无错写法:
define(‘ROOT’, dirname(__FILE__).DIRECTORY_SEPARATOR.”upload”);
这样就可以确保不会出错了。
例如discuz里面是这样写的:define(‘S_ROOT’, dirname(__FILE__).DIRECTORY_SEPARATOR);
回到问题本身上,DIRECTORY_SEPARATOR是一个返回跟操作系统相关的路径分隔符的php内置命令,在windows上返回,而在linux或者类unix上返回/,就是这么个区别,通常在定义包含文件路径或者上传保存目录的时候会用到
。
define('ROOT', dirname(__FILE__)."\upload");
在本地调试都很正常,但是上传到linux服务器后就会出错。所以如上代码严谨的写法为:
define('ROOT', dirname(__FILE__).DIRECTORY_SEPARATOR."upload");
提示:可以用函数get_defined_constants()来获取所有PHP常量,例如:
print_r(get_defined_constants());//get_defined_constants()返回所有常量数组
json_encode函数对于中文的操作不行同了,如果是uft8下还会碰到中文转成u590fu5a03u7684u8bf1u60d这种字符了,那么我们要如何输出成中文呢,下面来看看。
最近使用json_encode转换数组为json数据,储存在数据库里面,因为字段的长度个内容不确定,就只能使用这个方法了,但是使用json_decode解析为数组以后,却出现了类
似”u590fu5a03u7684u8bf1u60d14u5979u7684u6280u5de7″,通过查询百度,这应该是UCS-2编码的字符串,那么如何转换这个字符串呢?
其实在在php5.2以前的版本中做json_encode转换的时候的时候。中文会被unicode编码, php5.3加入了options参数, 5.4以后才加入JSON_UNESCAPED_UNICODE,这个参数,不需要做escape和unicode处理。 所以在5.4之前都需要对中文做个处理。
php5.4里面的处理
json_encode($str, JSON_UNESCAPED_UNICODE);
php5.4之前,有两种方法处理
方法一
function encode_json($str){ return preg_replace("/u([0-9a-f]+)/ie", "iconv('UCS-2', 'UTF-8', pack('H4', '\\1'))", $code); }
在实际应用中有个问题,部分字符会掉,不止为何,如字符串:”日期11.2″会被变成”日期.2″。
方法二
function encode_json($str) { return urldecode(json_encode(url_encode($str))); } function url_encode($str) { if(is_array($str)) { foreach($str as $key=>$value) { $str[urlencode($key)] = url_encode($value); } } else { $str = urlencode($str); } return $str; }
本站使用的是虚拟主机,就没法修改php的版本了,所以就只能采用第一种方法了,不过方法确实还是有效果的。
方法三 function decodeUnicode($str){ return preg_replace_callback('/\\\\u([0-9a-f]{4})/i', create_function( '$matches', 'return mb_convert_encoding(pack("H*", $matches[1]), "UTF-8", "UCS-2BE");' ), $str); }
相关文章
- 这篇文章主要介绍了c# socket网络编程,server端接收,client端发送数据,大家参考使用吧...2020-06-25
- 这篇文章主要介绍了JS WebSocket断开原因和心跳机制,对websocket感兴趣的同学,可以参考下...2021-05-08
- 这篇文章主要介绍了c# 线程同步的相关资料,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下...2020-08-29
- 这篇文章主要介绍了C#实现Socket通信的解决方法,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了C#中异步和多线程的相关资料,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下...2021-01-16
- 1. MySQL数据库主从同步延迟原理。要说延时原理,得从mysql的数据库主从复制原理说起,mysql的主从复制都是单线程的操作,主库对所有DDL和DML产生binlog,binlog是顺序写,所以效率很高,slave的Slave_IO_Running线程到主库取日...2013-10-04
- 多线程和异步操作两者都可以达到避免调用线程阻塞的目的,从而提高软件的可响应性。甚至有些时候我们就认为多线程和异步操作是等同的概念。但是,多线程和异步操作还是有一些区别的。而这些区别造成了使用多线程和异步操作的时机的区别...2020-06-25
- 本篇文章主要介绍了C# Socket异步通信,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
- 本篇文章主要介绍了C# Socket的TCP通讯,socket通讯方式有两种:同步和异步,详细的介绍了这两种方法,有兴趣的可以了解一下。...2020-06-25
- 这篇文章主要给大家介绍了关于JS异步的执行原理和回调的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-08
python使用socket高效传输视频数据帧(连续发送图片)
本文主要介绍了python使用socket高效传输视频数据帧(连续发送图片),文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-10-23- 我们在调试过程使用的工具有:modheader,postman等,但这些工具都会存在的问题:缺少客户端里相应的设备信息;即使将cookie信息复制出来,也是存在过期的问题;多个设备之间切换时不方便;针对这些存在的问题,我基于websocket双向通信的特点,实现了多端桥接管理平台...2021-05-15
- 这篇文章主要给大家介绍了关于c# winform异步不卡界面的实现方法,文中通过示例代码介绍的非常详细,对大家学习或者使用c#具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧...2020-06-25
- 这篇文章主要介绍了C语言中send()函数和sendto()函数的使用方法,是C语言入门学习中的基础知识,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了JQuery基于FormData异步提交数据文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-02
- 这篇文章主要介绍了C# 实现WebSocket服务端教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-12-08
- 这篇文章主要介绍了C#同步网络时间的方法,以实例形式较为详细的分析了C#获取网络时间与同步本机系统时间的相关技巧,非常具有实用价值,需要的朋友可以参考下...2020-06-25
- 本文章介绍两个实例来介绍mysql同步状态检测实现程序有需要的朋友可参考一下。 代码如下 复制代码 #!/bin/sh #check MySQL_Slave St...2016-11-25
- 这篇文章主要介绍了C# Socket编程实现简单的局域网聊天器,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
如何使用PHP+jQuery+MySQL实现异步加载ECharts地图数据(附源码下载)
ECharts地图主要用于地理区域数据的可视化,展示不同区域的数据分布信息,通过本文给大家介绍如何使用PHP+jQuery+MySQL实现异步加载ECharts地图数据,需要的朋友参考下吧...2016-02-26