在项目中发现经常有这种需求,需要加载一些大的固定的格式化数据,比如对战中的一些技能数据,物品等。这些数据都是只读数据,并且可能会比较大,目前来看大约有上万条复杂数据,如果serialize的话,纯文本有20M左右。尝试过直接放一个array在php文件里,结果发现require这个文件很耗时,可能会花费几十ms的时间,并且这个时候io很重,因为需要加载几十m数据到内存;另外去调研了一下sqlite,这个东西还算比较靠谱,但问题在于,比如写操作函数,使用起来很不爽;于是就产生了自己写一个扩展的想法。于是折腾之旅就此展开。
一开始想的是,直接在MINIT里调用zend_execute_script方法来加载一个php文件,返回一个zval来存储到全局变量里。结果后来仔细一琢磨发现根本就是妄想。原因在于MINIT的时候php的vm还没初始化完,不可能让你调用zend_execute_script方法,并且这个方法也不会返回一个zval,要想拿到zval必须从EG中去拿,很麻烦。
于是转换思路,尝试用unserialize/serialize,结果发现,php_var_unserialize在MINIT阶段果然是可以调用的。于是开搞,调用这个方法得到一个zval,然后存在全局变量里,在get方法里返回这个zval。写完之后,在测试的时候杯具的发现,只要调用就会core呀。于是查文档,自己思考,最终发现PHP_RSHUTDOWN_FUNCTION函数里会将所有非pealloc分配的的变量给清除。因此在MINIT阶段还正常的数据,到了Request阶段已经被free了。
于是再查文档,发现php里提供了pealloc这类函数来提供persistent的数据分配。于是再转换思路,将全局变量里的hashtable用pealloc来分配,并且将hastable设置成persistent的(谢天谢地php的hashtable还要存代码和vm,因此有这个功能)。但是杯具的是php_unserialize只会返回一个zval,你根本无法控制它是否是persistent的。没办法,只能调用zend_hash_copy来做了。写完之后再测试,发现还是core,这就不明白了,为啥呢?中午吃饭的时候,突然想到,可能是浅拷贝的问题,zend_hash_copy提供了一个copy函数而我没有设置它。再加上深拷贝函数之后再测试,发现果然可以用了,使用起来很清爽。 www.2cto.com
接下来进行测试发现,内存使用率不能忍,一个20m的数据文件加载到内存,需要大约100m左右的内存,如果有100个php-cgi进程,那就多要10G内存,这根本不能忍。于是设想,可以用共享内存来解决这个问题,反正这部分数据只要能读就行了。php-cgi的主进程负责MINIT操作,子进程只要读这部分数据就行了。但是很麻烦的是,php里没提供任何让用户维护内存的接口,于是只能一个函数一个函数的扒了。
仔细看了一下php的hashtable实现,发现比较复杂,而且关键用到了realloc函数,这个太让人无语了,总不能我也写一个内存管理吧。目前只用共享内存实现了一个简单的线程分配内存的函数,从共享内存上依次往后分配空间。但是还好,这部分功能是resize功能根本不需要。因为我的目标是将php_var_unserialize里得到的zval拷贝到共享内存而已,而大小我明显已经知道了。并且也不需要updatea功能,因为是全新的copy。最终弄完之后,发现可以使用了,内存使用率果然降了。
接下来进行压力测试,突然发现又开始core了,这根本不能忍呀,为啥呀?根据core文件,发现是里面的hashtable的refcount降到0了。于是各种测试,发现单线程情况下是ok的,只有多线程大压力情况下会挂。于是想到refcount是会被修改的,而且多线程修改的话,必须可能被改乱。那怎么办呢?总不能加锁吧。
后来仔细想了一下,突然想到只要我每次在返回这个zval里将顶层的zval的refcount修改为大于php-cgi进程数的值,那即使会被改乱也没啥问题,因为根本不会改到0。于是修改了之后再测试,发现果然靠谱了。
到此,整个问题基本解决。但是还有另外一个问题,在重启Php-cgi时还是会core,原因是,当时把正在使用的一些变量给强制写成0了。其实共享内存的正确用法是,一个进程来写,另外的进程来读,但是我这个应用里将共享内存当做绝对地址在使用,因此不可能在一个地方写,在其他地方读,除非shmat里的第二个参数修改为固定值,但是这个就需要对进程的地址分配有充分的了解,知道哪些内存根本不可能被使用。不过这个应该还好,因为Php-cgi进程有内存上限,所以应该可以找到一块内存在php-cgi运行过程中无法被用到的。不过具体的情况得接下来具体研究一下。
作者 无心云

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

在php中,可以使用substr()函数来读取字符串后几个字符,只需要将该函数的第二个参数设置为负值,第三个参数省略即可;语法为“substr(字符串,-n)”,表示读取从字符串结尾处向前数第n个字符开始,直到字符串结尾的全部字符。

方法:1、用“str_replace(" ","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\ \;||\xc2\xa0)/","其他字符",$str)”语句。

php判断有没有小数点的方法:1、使用“strpos(数字字符串,'.')”语法,如果返回小数点在字符串中第一次出现的位置,则有小数点;2、使用“strrpos(数字字符串,'.')”语句,如果返回小数点在字符串中最后一次出现的位置,则有。


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

SublimeText3 Mac version
God-level code editing software (SublimeText3)

SAP NetWeaver Server Adapter for Eclipse
Integrate Eclipse with SAP NetWeaver application server.

Zend Studio 13.0.1
Powerful PHP integrated development environment
