首页
关于
Search
1
给你10个市场数据调研报告的免费下载网站!以后竞品数据就从这里找!
185 阅读
2
php接口优化 使用curl_multi_init批量请求
144 阅读
3
《从菜鸟到大师之路 ElasticSearch 篇》
107 阅读
4
2024年备考系统架构设计师
104 阅读
5
PHP 文件I/O
92 阅读
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
登录
Search
标签搜索
php函数
php语法
性能优化
安全
错误和异常处理
问题
vue
Composer
Session
缓存
框架
Swoole
api
并发
异步
正则表达式
php-fpm
mysql 索引
开发规范
协程
dafenqi
累计撰写
786
篇文章
累计收到
33
条评论
首页
栏目
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
副业
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
页面
关于
搜索到
786
篇与
的结果
2023-08-08
关于PHP你可能不知道的-PHP的事件驱动化设计
关于PHP你可能不知道的-PHP的事件驱动化设计最近在做一个需要用到异步PHP的项目, 翻阅PHP源码的时候,发现了三个没有用过的模块,sysvsem,sysvshm,sysvmsg,一番研究以后,受益非浅。在PHP中有这么一族函数,他们是对UNIX的V IPC函数族的包装。它们很少被人们用到,但是它们却很强大。巧妙的运用它们,可以让你事倍功半。它们包括:信号量(Semaphores)共享内存(Shared Memory)进程间通信(Inter-Process Messaging, IPC)基于这些,我们完全有可能将PHP包装成一基于消息驱动的系统。但是,首先,我们需要介绍几个重要的基础:ftokint ftok ( string pathname, string proj )//ftok将一个路径名pathname和一个项目名(必须为一个字符), 转化成一个整形的用来使用系统V IPC的keyticksTicks是从PHP 4.0.3开始才加入到PHP中的,它是一个在declare代码段中解释器每执行N条低级语句就会发生的事件。N的值是在declare中的directive部分用ticks=N来指定的。function getStatus($arg){ print_r connection_status(); debug_print_backtrace();}reigster_tick_function("getStatus", true);declare(ticks=1){ for($i =1; $i<999; $i++){ echo "hello"; }}unregister_tick_function("getStatus");这个就基本相当于:function getStatus($arg){ print_r connection_status(); debug_print_backtrace();}reigster_tick_function("getStatus", true);declare(ticks=1){ for($i =1; $i<999; $i++){ echo "hello"; getStatus(true); }}unregister_tick_function("getStatus");消息,我现在用一个例子来说明,如何结合Ticks来实现PHP的消息通信。$mesg_key = ftok(__FILE__, 'm');$mesg_id = msg_get_queue($mesg_key, 0666);function fetchMessage($mesg_id){ if(!is_resource($mesg_id)){ print_r("Mesg Queue is not Ready"); } if(msg_receive($mesg_id, 0, $mesg_type, 1024, $mesg, false, MSG_IPC_NOWAIT)){ print_r("Process got a new incoming MSG: $mesg "); }}register_tick_function("fetchMessage", $mesg_id);declare(ticks=2){ $i = 0; while(++$i < 100){ if($i%5 == 0){ msg_send($mesg_id, 1, "Hi: Now Index is :". $i); } }}//msg_remove_queue($mesg_id);在这个例子中,首先将我们的PHP执行Process加入到一个由ftok生成的Key所获得的消息队列中。然后,通过Ticks,没隔俩个语句,就去查询一次消息队列。然后模拟了消息发送。在浏览器访问这个脚本,结果如下:Process got a new incoming MSG: s:19:"Hi: Now Index is :5";Process got a new incoming MSG: s:20:"Hi: Now Index is :10";Process got a new incoming MSG: s:20:"Hi: Now Index is :15";Process got a new incoming MSG: s:20:"Hi: Now Index is :20";Process got a new incoming MSG: s:20:"Hi: Now Index is :25";Process got a new incoming MSG: s:20:"Hi: Now Index is :30";Process got a new incoming MSG: s:20:"Hi: Now Index is :35";Process got a new incoming MSG: s:20:"Hi: Now Index is :40";Process got a new incoming MSG: s:20:"Hi: Now Index is :45";Process got a new incoming MSG: s:20:"Hi: Now Index is :50";Process got a new incoming MSG: s:20:"Hi: Now Index is :55";Process got a new incoming MSG: s:20:"Hi: Now Index is :60";Process got a new incoming MSG: s:20:"Hi: Now Index is :65";Process got a new incoming MSG: s:20:"Hi: Now Index is :70";Process got a new incoming MSG: s:20:"Hi: Now Index is :75";Process got a new incoming MSG: s:20:"Hi: Now Index is :80";Process got a new incoming MSG: s:20:"Hi: Now Index is :85";Process got a new incoming MSG: s:20:"Hi: Now Index is :90";Process got a new incoming MSG: s:20:"Hi: Now Index is :95";看到这里是不是,大家已经对怎么模拟PHP为事件驱动已经有了一个概念了? 别急,我们继续完善。信号量信号量的概念,大家应该都很熟悉。通过信号量,可以实现进程通信,竞争等。 再次就不赘述了,只是简单的列出PHP中提供的信号量函数集。sem_acquire -- Acquire a semaphoresem_get -- Get a semaphore idsem_release -- Release a semaphoresem_remove -- Remove a semaphore具体信息,可以翻阅PHP手册。内存共享PHP sysvshm提供了一个内存共享方案:sysvshm,它是和sysvsem,sysvmsg一个系列的,但在此处,我并没有使用它,我使用的shmop系列函数,结合TIcksfunction memoryUsage(){ printf("%s: %s<br/>", date("H:i:s", $now), memory_get_usage()); //var_dump(debug_backtrace()); //var_dump(__FUNCTION__); //debug_print_backtrace();}register_tick_function("memoryUsage");declare(ticks=1){$shm_key = ftok(__FILE__, 's');$shm_id = shmop_open($shm_key, 'c', 0644, 100);}printf("Size of Shared Memory is: %s<br/>", shmop_size($shm_id));$shm_text = shmop_read($shm_id, 0, 100);eval($shm_text);if(!empty($share_array)){ var_dump($share_array); $share_array['id'] += 1;}else{ $share_array = array('id' => 1);}$out_put_str = "$share_array = " . var_export($share_array, true) .";";$out_put_str = str_pad($out_put_str, 100, " ", STR_PAD_RIGHT);shmop_write($shm_id, $out_put_str, 0);?>运行这个例子,不断刷新,我们可以看到index在递增。单单使用这个shmop就能完成一下,PHP脚本之间共享数据的功能:以及,比如缓存,计数等等。
2023年08月08日
9 阅读
0 评论
0 点赞
2023-08-08
PHP 高级编程之多线程
PHP 高级编程之多线程
2023年08月08日
13 阅读
0 评论
0 点赞
2023-08-08
PHP异步并发访问mysql简单实现
PHP异步并发访问mysql简单实现在实际的开发过程中,我们常常会遇到需要操作多张表,多个库的情况。有时因为一些限制我们不能进行连表(例如,异地数据库),所以只能用php串行访问后再在php里进行合并,有时还需要模拟mysql对合并后的结果进行排序、归并等。这里产生的一个问题就是串行带来的访问时间问题。由于传统的串行访问方式,我们只能等到一条sql执行完毕后才可以执行下一条,所以执行时间是累加的。PHP官方手册提供了一种可以异步并发访问mysql的方式,详见:http://php.net/manual/zh/mysqli.poll.php,参考资料:https://svn.osgeo.org/mapguide/sandbox/rfc94/Oem/php/ext/mysqli/tests/mysqli_poll.phpt,使用此种方式,我们可以对Mysql进行异步并发访问,访问时间不再是串行累加,而是取决于执行时间最长的sql。项目地址:https://github.com/huyanping/async-mysql-phpshow you the code: try{ $async_mysql = new \Jenner\Mysql\Async(); $async_mysql->attach( ['host' => '127.0.0.1', 'user' => 'root', 'password' => '', 'database' => 'test'], 'select * from stu' ); $async_mysql->attach( ['host' => '127.0.0.1', 'user' => 'root', 'password' => '', 'database' => 'test'], 'select * from stu limit 0, 3' ); $result = $async_mysql->execute(); print_r($result); }catch (Exception $e){ echo $e->getMessage(); }async_mysql对象对mysql进行异步并发访问,attach方法接收每个请求必须的配置信息,execute方法为执行入口,其返回值是每条sql执行结果的数组,顺序与attach调用顺序一致。当任何一个连接mysql出错或执行任何一条sql出错,都会引起异常抛出。这样设计主要是基于完整性的考虑,我们把所有需要执行的sql看做是一个整体事务,任何一个执行失败,则认为该事务失败。composer信息:"require":{ "jenner/async-mysql-php": "v0.1" }或者直接引入/path/to/async-mysql-php/autoload.php文件最后在阿里云上做了一个简单的测试,测试结果如下:# 同步 [root@iZ942077c78Z async-mysql-php]# php tests/performance_sync.php ------------------------------------------ mark:[total diff] time:4.2648551464081s memory_real:18944KB memory_emalloc:18377.171875KB memory_peak_real:28416KB memory_peak_emalloc:27560.3828125KB [root@iZ942077c78Z async-mysql-php]# php tests/performance_sync.php ------------------------------------------ mark:[total diff] time:4.2285549640656s memory_real:18944KB memory_emalloc:18377.171875KB memory_peak_real:28416KB memory_peak_emalloc:27560.3828125KB [root@iZ942077c78Z async-mysql-php]# php tests/performance_async.php ------------------------------------------ mark:[total diff] time:1.455677986145s memory_real:38144KB memory_emalloc:32574.015625KB memory_peak_real:66816KB memory_peak_emalloc:65709.7734375KB # 异步 [root@iZ942077c78Z async-mysql-php]# php tests/performance_async.php ------------------------------------------ mark:[total diff] time:1.8936941623688s memory_real:38144KB memory_emalloc:32574.015625KB memory_peak_real:66816KB memory_peak_emalloc:65709.7734375KB [root@iZ942077c78Z async-mysql-php]# php tests/performance_async.php ------------------------------------------ mark:[total diff] time:1.5208158493042s memory_real:38144KB memory_emalloc:32574.015625KB memory_peak_real:66816KB memory_peak_emalloc:65709.7734375KB实际上以上测试结果并没有太大意义。因为理论上这种异步并发的访问方式会绝对优于传统的串行访问方式,再次需要说明的是,访问数据库的时间接近执行时间最长的SQL。由于同一时间要处理多个SQL返回的结果,程序需要连续申请多个内存空间用于存储SQL的返回结果。所以使用这种方式会造成内存翻倍。从下面的测试结果来看,内存基本位置在两倍以内(测试程序执行了两条SQL)。到了这一步,我们已经可以实现对mysql进行异步并发访问了。如果我们还需要做多个数组的归并,可以使用《PHP模拟SQL的GROUP BY算法》中介绍的方法。其中提供的归并方式非常灵活,更胜mysql原生的group by。如果还需要对合并后的结果做排序,可以使用https://github.com/huyanping/Zebra-Tools/blob/master/src/Jenner/Zebra/Tools/CommonArray.php#L90这段代码实现,非常方便。改函数来源于php手册http://php.net/manual/zh/function.array-multisort.php
2023年08月08日
9 阅读
0 评论
0 点赞
2023-08-08
PHP 线程,进程和并发
PHP 线程,进程和并发进程进程是什么?进程是正在执行的程序;进程是正在计算机上执行的程序实例;进程是能分配给处理器并由处理器执行的实体。 进程一般会包括指令集和系统资源集,这里的指令集是指程序代码,这里的系统资源集是指I/O、CPU、内存等。 综合起来,我们也可以理解进程是具有一定独立功能的程序在关于某个数据集合上的一次运行活动, 进程是系统进行资源分配和调度的一个独立单位。在进程执行时,进程都可以被唯一的表示,由以下一些元素组成:进程描述符:进程的唯一标识符,用来和其它进程区分。在Linux中叫进程ID,在系统调用fork期间生成,只是我们通过getpid返回的不是其pid字段,而是其线程组号tgid。进程状态:我们常说的挂起、运行等状态,其表示的是当前的状态。优先级:进程间的执行调度相关,相对于其它进程而言。程序计数器:程序中即将被执行的下一条指令的地址,该地址是内核术中或用户内存空间中的内存地址。内存指针:包括程序代码和进程相关数据的指针,还有和其它进程共享内存块的指针。上下文数据:进程执行时处理器的寄存器的数据。I/O状态信息:包括显式的I/O请求、分配给进程的I/O设备等记账信息:可能包括处理器时间总和、使用的时钟数总和、时间限制等以上的这些元素都会放在一个叫做进程控制块的数据结构中。进程控制块是操作系统能够支持多进程和提供多处理的结构。 当操作系统做进程切换时,它会执行两步操作,一是中断当前处理器中的进程,二是执行下一个进程。 不管是中断还是执行,进程控制块中的程序计数器、上下文数据和进程状态都会发生变化。 当进程中断时,操作系统会把程序计数器和处理器寄存器(对应进程控制块中的上下文数据)保存到进程控制块中的相应位置, 进程状态也会有所变化,可能进入阻塞状态,也有可能进入就绪态。 当执行下一个进程时,操作系统按规则将下一个进程设置为运行态,并加载即将要执行进程的程序上下文数据和程序计数器等。线程进程有两个特性部分:资源所有权和调度执行。 资源所有权是指进程包括了进程运行所需要的内存空间、I/O等资源。 调度执行是指进程执行过程中间的执行路径,或者说程序的指令执行流。 这两个特性部分是可以分开的,分开后,拥有资料所有权的通常称为进程,拥有执行代码的可分派部分的被称之为线程或轻量级进程。线程有“执行的线索”的意思在里面,而进程在多线程环境中被定义为资源所有者,其还是会存储进程的进程控制块。 线程的结构与进程不同,每个线程包括:线程状态: 线程当前的状态。一个执行栈私有的数据区: 用于每个线程局部变量的静态存储空间寄存器集: 存储处理器的一些状态每个进程都有一个进程控制块和用户地址空间,每个线程都有一个独立的栈和独立的控制块,都有自己一个独立执行上下文。 其结构如图8.1所示。hread-model图8.1 进程模型图线程在执行过程中与进程有一些不同。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。 但是线程不能够独立执行,必须依存在于进程之中,由进程提供多个线程执行控制。 从逻辑角度来看,多线程的意义在于一个进程中,有多个执行部分可以同时执行。 此时,进程本身不是基本运行单位,而是线程的容器。线程较之进程,其优势在于一个快,不管是创建新的线程还是终止一个线程;不管是线程间的切换还是线程间共享数据或通信,其速度与进程相比都有较大的优势。并发及并行并发又称共行,是指能处理多个同时性活动的能力,并发事件之间不一定要同一时刻发生。 比如,现代计算机系统可在同一段时间内以进程的形式将多个程序加载到存储器中,并借由处理器的时分复用, 以在一个处理器上表现出同时运行的感觉。并行是指同时发生的两个并发事件,具有并发的含义,而并发则不一定并行。并发和并行的区别就是一个处理器同时处理多个任务和多个处理器或者是多核的处理器同时处理多个不同的任务。 前者是逻辑上的同时发生(simultaneous),而后者是物理上的同时发生。PHP的各种并发模型既然有两种模型,那么PHP使用的是哪一种呢?答案是都支持,也就是说PHP支持多线程的模型, 在多线程情况下通常要解决资源共享和隔离的问题。PHP本身是线程安全的。具体来说是那种模型需要看使用的是哪个SAPI,比如说在Apache中,那么就可能使用多线程模型, 也可能使用多进程模型。而php-fpm使用的就是多进程模型。目前比较推荐的方式是使用php-fpm的模型,因为这个模型对于PHP来说有诸多的优势:内存释放简单,使用多进程模型时进程可以容易通过退出的方式来释放内存, 由于PHP有非常多的扩展,稍有不慎就可能导致内存泄露,fpm通过进程退出方式 简单除暴的解决了问题。容灾能力强,同样的问题,扩展或者php可能会出现段错误,如果是单进程多线程模型, 那么整个PHP就挂掉了。这会影响服务,多进程的话,某个进程死掉了也不会影响整体的服务。多进程有多进程的优势,多线程也有多线程的优势,比如HHVM它选择的是多线程模型。 多线程模型最大的好处是信息共享和通信方便,因为在同一个进程空间内,可以直接使用指针。比如opcode cache工具,在PHP里,apc以及opcache等等使用的是共享内存来共享opcode, 那么在HHVM中则不需要走共享内存,共享内存还有个问题是存储复杂的数据结构不方便, 因为指针的问题,多线程情况下C/C++中的数据结构是可以共享的。这对效率提升也是有帮助的。多进程和多线程还有一个明显的模型区别:在处理请求时的逻辑。在多进程情况下,由于跨进程是不好传递fd连接的。那么多进程通常采用在父进程中listen(), 然后各个子进程accept()的方式来实现负载均衡。这样的模型下可能会有惊群的问题。而多线程模型下,可以采用一个独立线程接受请求然后派发到各个worker线程的方式。参考资料《操作系统精髓与设计原理》
2023年08月08日
16 阅读
0 评论
0 点赞
2023-08-08
关于编程语言
关于编程语言最近群里很多朋友询问我是如何学习编程的,今天抽个时间大致讲讲。C语言和所有人一样,上学学的第一门编程语言是C语言。我记得我当时学的很认真,非常认真。和别人最大的不同是我买了一本老外写的C语言编程书,没被谭浩强误导。另外还买了一本《现代操作系统》一书看了很久。学习期间写了不少读书笔记。真正要说学到什么了,这个还真不好说,到最后我对C语言也是似懂非懂的状态。用学物理、数学的方法学编程语言是行不通的,编程需要的是实践。Java学Java的目的很明确,为了找一份好工作。面向对象、J2EE、Java设计模式、SSH的书买了好几本。最后还是没能够入门。原因我后来分析主要是2点,1、Java太复杂了,根本就不适合初学者。2、犯了和学习C语言同样的错误,读书太多,实践太少(主要是不会搭建Java的开发环境)。PHP偶然的机会了解到了PHP语言,按照网上的教程一搞,写了一个MySQL的网页程序,竟然运行成功了。这实在太神奇了。你们无法理解当时我的心情,可以说到了 高兴地3天不用吃饭的程度。呵呵,当时我就下定决心以后就是它了。PHP让我进入了一个新的境界,我可以大量地实践,写出各种程序。而且也顺利找到了工作,干的风生水起,一个接一个地做了很多项目。后来又进入腾讯,在腾讯有机会去开发维护一个超过2亿用户,日活超过8千万,机器规模超过1000多台的超大系统。我的人生的各种成果都归功于PHP这门伟大的编程语言。重新回到C语言当然后面也逐渐认识到PHP的不足,不过很快我就发现可以写C扩展来弥补。重新学起C语言,我发现竟然很顺利。原因应该是我在写PHP程序的过程中,工程实践能力已经磨练到非同一般。其实不只是C语言,只要我愿意,C++,Java,Python,Golang任何语言都可以快速掌握。然后就开始搞Swoole这个项目,边学边做。经过这2年的时间,现在可以说我已经掌握C语言了。为什么会回到C语言,原因很简单:所有底层软件都是C语言写的,包括操作系统、底层库、驱动、其他编程语言本身。C语言一切现代软件技术的根源。我的个人感悟我的编程之路轨迹就是 C语言(起始) -> Java(过客)-> PHP(主)-> C语言(终点)。编程语言专注于一个就行了,Java、PHP、Python、Ruby 任意一个都行。只要能把一门编程语言学精通,其他语言学起来也很容易。工作时选择的编程语言,应该是一主多辅。做Web得了解Javascript,做APP需要掌握Android、Object-C,写桌面程序需要学习C++。带着问题去学就好了。不要选择难或者复杂的编程语言作为入门,易于上手的编程语言更容易成功。公司有一个搞Java 9年的人,技术等级很低。很好的例子。另外一个只工作了5年的PHPer现在已经是T3-2的技术Leader了。编程最核心的是动手实践多看一看别的编程语言和技术,开阔一下视野编程做到最后还是会回到C语言的,当然很多人中途就已经离开编程岗位了
2023年08月08日
12 阅读
0 评论
0 点赞
1
...
111
112
113
...
158