/首页
/开源
/关于
PHP网络编程-进程控制篇(四)
发表@2019-12-02 09:59:00
更新@2023-03-26 18:34:49
各位佬们腿子们好,我是老李。 不知不觉已经干到第四章了,三条消息,一好一坏一中性: - 好消息是进程部分的基础内容再写一个章节就终于能结束了 - 坏消息是下下一章节我们要分析WM有关进程的部分实现 - 然后是后面准备进入socket部分了,开不开心,刺不刺激  昨天晚上做梦梦到了栋子,就想起我俩那会儿一起摸鱼的时光。那还是五年前在[ 黑 ]鹭引擎的时候,我俩被人称为公司两大门神,具体表现在于基本一整个白天都在公司门口歇着摸鱼,就坐楼下的石凳上一边一个,各摸各的十分对称十分默契。 当然了我俩都认为各有各摸鱼的道理,比如栋子总是觉得自己的UI设计风格属于写实主义而不被公司重用,而我则是认为这是因为我尝试在公司推swoole推不动而觉得怀才不遇。相比之下由于我总是能在适当时候用类似于[ 行路难!行路难!多歧路,今安在? ]或[ 念天地之悠悠,独怆然而涕下 ]等多种不同的诗句来花式地表达自己,而栋子则因为长期的文化匮乏每次只能狠嘬一口白沙后恶狠狠地说同一句话[ 尚能饭否!尚能饭否!]... 终于有一天栋子似乎良心发现了,那天我一下去就觉得他有话要说,果不其然(由于事隔已久远,具体已经记不太清了,大概意思如下)。栋子闷了一口白沙后,漠然抬头用散乱的眼神看了一眼前方,然后收了收嗓子很严肃认真地跟我说: - ... ...老李,我现在严重怀疑我被公司雪藏了...... - 我:??????啥意思??? - 我:... ...或者说是有什么具体表现吗?... - 栋子看了我一眼,本来想嘬一口香烟又不自觉挪开了嘴巴,顿了顿神后偷偷摸摸看了看四周,然后神神叨叨地低声跟我说:你说这都半年多了,公司啥活儿也不给我安排... ... - 我:??????... ... - 我:...扣你工资了?... ... - 栋子:没有啊,老样子按时发啊... - 我:。。。。。。 - 我:... 我说铁子,真TM新鲜了,MD我这是头次见有人把骗工资说的这么清新脱俗... ... 五年过去了,人已经回不到过去了,时代也回不去了... 记得后来没多久,领导让我研究一个爬虫脚本,当时为了不让脚本莫名其妙退出就天天看着电脑不关机,再后来就用Linux命令后加一个[ & ]符来跑...莫名其妙挂了几次后,我决定彻底研究一下[ 如何使程序在后台保持稳定 ]这个话题,当然了这也是我们今天的话题。 如何才能使程序溜到后台里?我先说个著名的[ & ]符,感受下: ```php 0 ) { //exit; //} // 守护进程的业务逻辑从这里开始 // while使得进程不会退出,一般http服务器等都是event-loop不会退出 while ( true ) { sleep( 1 ); } } // 父进程退出 else if ( $i_pid > 0 ) { exit(); } ``` 上述代码中我注释了一行关于二次fork的代码,这段代码你可以用,也可以不用,注释里我写了一下原因。上述代码保存好运行一下,然后我们用ps命令感受一下:  此时daemon.php在调用了setsid后自己新建了一个进程组且自己为组长进程、自己新建了一个会话组且自己为会话组长、自己脱离了控制终端且由于父进程已经exit退出所以由1号进程即init进程收养。为了说明我们的daemon进程是完美的、是和大厂出品一样牛13的,我特意整了一把Redis,你们对比感受一下。 现在好了,我们有了daemon的标准做法,就可以尝试做一些东西了,我简单举个例子你们感受一下: ```php 0 ) { exit; } //echo "here".PHP_EOL; } // 父进程退出 else if ( $i_pid > 0 ) { exit(); } } // 首先执行daemonize函数,使得进程daemon化 daemonize(); // 连接redis,在后台做一些事情 $o_redis = new Redis(); $o_redis->connect( '127.0.0.1', 6379 ); while ( true ) { echo $o_redis->get( 'user:1' ).PHP_EOL; sleep( 1 ); } ``` 上面代码运行后,你一定会发现一个问题:那就是当前终端会不会打印出空行。这个嘛,哈,这个是因为我们没有重定向标准输出到文件中导致的,所以上述的daemonize函数实际上并不完善,只是完成了最重要的功能。一个较为完善的daemonize函数,应该具备如下要点: - 设置好umask - 将目录切换到根目录,避免默认工作目录被daemon进程占据无法卸载 - 关闭标准输出等或将其重定向到指定地方 所以一个稍微完善点儿的daemonize应该是这样的,你们赶紧复制粘贴走试试: ```php 0 ) { exit; } // 关闭 标准输入 // 这里仅仅是关闭,你可以根据你的需要重定向到其他位置,比如某些文件 fclose( STDOUT ); } // 父进程退出 else if ( $i_pid > 0 ) { exit(); } } // 首先执行daemonize函数,使得进程daemon化 daemonize(); // 连接redis,在后台做一些事情 $o_redis = new Redis(); $o_redis->connect( '127.0.0.1', 6379 ); while ( true ) { echo $o_redis->get( 'user:1' ).PHP_EOL; sleep( 1 ); } ```