PHP多线程pthreads踩坑记

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mzc186/article/details/81108165

最近由于项目需求,对配资订单需要间隔自动扫描(例如5s或者10s的时间间隔),筛选出未结算的订单所对应的股票代码,然后去拉取最新的股票数据,然后再综合各项约束筛选出要结算的订单,然后暂时设定这些订单为结算中状态(以防后续的结算任务请求和当前的结算任务冲突),然后进行订单结算,然后再释放订单的结算状态。

方案是这么设想的,但问题是如果有很多不同的股票代码需要同时拉取最新数据,又要同时保持5s的刷新频率,如果仅仅用单线程,很可能第一个结算任务过了5s甚至10s都还没有完成,但第二甚至第三个任务又启动起来了,这一方面有可能造成数据冲突,另一方面就是结算速度太慢了不仅影响体验而且可能造成进程数越来越多服务器到最后卡死。如果同时一次性将各个不同的股票代码组合起来,统一一次性去拉取最新的股票数据也是可行的一个方式,但如果股票代码多,对应的需要结算的订单多还是会出现服务器卡死的情况。

所以,我们自然会考虑多线程或者多进程,但多进程占用资源比较多,如果进程数比较多的话同样容易使机器变得卡死,多线程理论上也会有这样的问题,但是毕竟比进程轻量许多,所以,就想到使用多线程来做订单的并行结算可能比较合适。

但php本身是不支持多线程的,需要安装扩展,而安装pthreads扩展需要zts版本的php,在linux系统里需要自己重新编译php源代码并带上 –enable-maintainer-zts选项。

然而环境搭好以后你以为就可以轻松地进行php多线程变成了吗?too young. 有些系统的函数在zts版本的php下可能会执行不成功,而且没有任何报错,会被直接忽略,所以你也不好调试;而多线程的代码调试起来难度本身又更大。所以造成了用pthreads扩展来进行多线程编程其实体验是很差的,而且案例少,资料少,而且pthreads的源码已经有3年左右没有更新过了,所以使用pthreads进行php的多线程编程其实并不是一个明智之举,pthreads并不是php的一个多线程的成熟解决方案,只不目前而言php没得选择,因为原生php是不支持多线程的,所以说这也是php的一个比较大的弱点,毕竟现代的网络应用,高并发可以说是非常常见的典型场景了。

在使用pthreads进行多线程编程过程中,目前发现了以下几个坑:
(1)有些系统函数在zts版本中,在多线程的run方法中执行不成功,比如file_put_contents(),可能需要的配置环境不一样,就像第二点一样。
(2)zts版本的php执行有关时间的php脚本会要求设置default_time_zone,可以动态设置,也可以在php.ini里设置date.time_zone=PRC(推荐),因为php.ini里设置了,那么run方法里面有涉及到时间的代码才不会出错,动态设置的在这种情况就会出错。
(3)多线程代码不好调试,而且如前述,有些代码在普通版本的php里执行是没有问题的,但在zts版本里执行就是执行不成功甚至没有任何错误提示。针对这种情况,目前想到的就是先把线程的run方法当作普通方法来调用,先测试一下。对于没有任何错误提示的情况可以考虑xdebug,另外我用try catch也捕获过异常,从而获得了一些错误提示信息。

猜你喜欢

转载自blog.csdn.net/mzc186/article/details/81108165
今日推荐