php getmypid,php进程通信-进程信号

快一个月没发博文了,之前都在深入研究php多进程tcp服务器,结果到现在也没搞出一个完美的解决方案,所以还是先发下这个月学到的东西吧

注意:本文所有内容均在linux环境下

一:进程信号对照

在php进程信号常量中,有定义以下常量(该表格参考网上的,不完整)

信号名信号值信号类型信号说明

SIGHUP1终止进程(终端线路挂断)本信号在用户终端连接(正常或非正常、结束时发出, 通常是在终端的控制进程结束时, 通知同一session内的各个作业, 这时它们与控制终端不再关联.

SIGINT2终止进程(中断进程)程序终止(interrupt、信号, 在用户键入INTR字符(通常是Ctrl-C、时发出

SIGQUIT3建立CORE文件终止进程,并且生成CORE文件SIGQUIT 和SIGINT类似, 但由QUIT字符(通常是Ctrl-、来控制. 进程在因收到SIGQUIT退出时会产生core文件, 在这个意义上类似于一个程序错误信 号.

SIGILL4建立CORE文件(非法指令)SIGILL 执行了非法指令. 通常是因为可执行文件本身出现错误, 或者试图执行数据段. 堆栈溢出时也有可能产生这个信号.

SIGTRAP5建立CORE文件(跟踪自陷)SIGTRAP 由断点指令或其它trap指令产生. 由debugger使用.

SIGABRT6SIGABRT 程序自己发现错误并调用abort时产生.

SIGIOT6建立CORE文件(执行I/O自陷)SIGIOT 在PDP-11上由iot指令产生, 在其它机器上和SIGABRT一样.

SIGBUS7建立CORE文件(总线错误)SIGBUS 非法地址, 包括内存地址对齐(alignment、出错. eg: 访问一个四个字长的整数, 但其地址不是4的倍数.

SIGFPE8建立CORE文件(浮点异常)SIGFPE 在发生致命的算术运算错误时发出. 不仅包括浮点运算错误, 还包括溢 出及除数为0等其它所有的算术的错误.

SIGKILL9终止进程(杀死进程)SIGKILL 用来立即结束程序的运行. 本信号不能被阻塞, 处理和忽略.

SIGUSR110终止进程(用户自定义信号1)SIGUSR1 留给用户使用

SIGSEGV11SIGSEGV 试图访问未分配给自己的内存, 或试图往没有写权限的内存地址写数据.

SIGUSR212终止进程(用户自定义信号2)SIGUSR2 留给用户使用

SIGPIPE13终止进程(向一个没有读进程的管道写数据)Broken pipe

SIGALRM14终止进程(计时器到时)SIGALRM 时钟定时信号, 计算的是实际的时间或时钟时间. alarm函数使用该信号.

SIGTERM15终止进程(软件终止信号)SIGTERM 程序结束(terminate、信号, 与SIGKILL不同的是该信号可以被阻塞和处理. 通常用来要求程序自己正常退出. shell命令kill缺省产生这个信号.

SIGCHLD17忽略信号(当子进程停止或退出时通知父进程)SIGCHLD 子进程结束时, 父进程会收到这个信号.

SIGCONT18忽略信号(继续执行一个停止的进程)SIGCONT 让一个停止(stopped、的进程继续执行. 本信号不能被阻塞. 可以用一个handler来让程序在由stopped状态变为继续执行时完成特定的工作. 例如, 重新显示提示符

SIGSTOP19停止进程(非终端信号)SIGSTOP 停止(stopped、进程的执行. 注意它和terminate以及interrupt的区别: 该进程还未结束, 只是暂停执行. 本信号不能被阻塞, 处理或忽略.

SIGTSTP20停止进程(终端信号)SIGTSTP 停止进程的运行, 但该信号可以被处理和忽略. 用户键入SUSP字符时 (通常是Ctrl-Z、发出这个信号

SIGTTIN21停止进程(后端进程读终端)SIGTTIN 当后台作业要从用户终端读数据时, 该作业中的所有进程会收到SIGTTIN 信号. 缺省时这些进程会停止执行.

SIGTTOU22停止进程(后端进程写终端)SIGTTOU 类似于SIGTTIN, 但在写终端(或修改终端模式、时收到.

SIGURG23忽略信号(I/O紧急信号)SIGURG 有”紧急”数据或out-of-band数据到达socket时产生.

SIGXCPU24终止进程(CPU实现超时)SIGXCPU 超过CPU时间资源限制. 这个限制可以由getrlimit/setrlimit来读取/ 改变

SIGXFSZ25终止进程(文件长度过长)SIGXFSZ 超过文件大小资源限制.

SIGVTALRM26终止进程(虚拟计时器到时)SIGVTALRM 虚拟时钟信号. 类似于SIGALRM, 但是计算的是该进程占用的CPU时间.

SIGPROF27终止进程(统计分布图用计时器到时)SIGPROF 类似于SIGALRM/SIGVTALRM, 但包括该进程用的CPU时间以及系统调用的 时间.

SIGWINCH28忽略信号(窗口大小发生变化)SIGWINCH 窗口大小改变时发出.

SIGIO29忽略信号(描述符上可以进行I/O)SIGIO 文件描述符准备就绪, 可以开始进行输入/输出操作.

SIGPWR30SIGPWR Power failure

二:php基础进程相关函数

注意:(需要pcntl扩展支持)

1:declare(ticks=1);每执行一条php低级语句,则触发一次register_tick_function函数,并且每执行1条低级语句会检查一次该进程是否有未处理过的信号.,该函数是在php版本小于5.3,用于php进行php信号处理的函数,例如:<?php

declare(ticks=1);//每执行一条时,触发register_tick_function()注册的函数

$a=1;//再注册之前,不记录

$a=1;//再注册之前,不记录

function test(){//定义一个函数

echo "执行\n";

}

register_tick_function('test');//该条注册函数会被当成低级语句被执行

for($i=0;$i<=3;$i++){//for算一条低级语句

$i=$i;//赋值算一条

}

在php7.2中,运行结果如下:

9574f616c9ae43eeef2ffea390c50d5d.png

2:pcntl_signal;注册一个信号处理函数,和declare(ticks=1)组合使用:declare(ticks = 1);

pcntl_signal(SIGINT,function(){

echo "触发信号Ctrl+c";

});

while(1){

sleep(1);//死循环运行低级语句

}

当执行该脚本,再ctrl+c的时候,将会捕捉到该信号,并输出,如图:

355baf8510abff36f925c0878e516d56.png

3:getmypid.获取当前进程id,posix_kill发送信号

为什么会拿这2个一起说呢?因为posix_kill函数如果需要发送信号,是需要进程id的,而getmypid(),则是获取当前进程id的函数,

以下是将上面的函数组合使用的例子:<?php

//文件一

declare(ticks = 1);

echo getmypid();//获取当前进程id

pcntl_signal(SIGUSR1,function(){

echo "触发信号用户自定义信号1";

});

while(1){

sleep(1);//死循环运行低级语句

}<?php

//文件二

posix_kill(文件一进程, SIGUSR1);

运行文件1结果:

c73cccc12e00fd5927a1a9a8b1d865db.png

运行文件2之后文件1结果:

aeced44c7037b1211ee26e62529bd07c.png

4:到这之后,你可能会想到,declare每次运行一次低级语句,都会尝试执行2种结果,效率会不会很差呢?答案是会的,所以在php5.3之后,有了新的函数,那就是pcntl_signal_dispatch

pcntl_signal_dispatch:调用等待信号的处理器,有了它,将不在需要declare,只需要在循环中增加该函数,就可以调用信号通过了:<?php

echo getmypid();//获取当前进程id

pcntl_signal(SIGUSR1,function(){

echo "触发信号用户自定义信号1";

});

while(1){

pcntl_signal_dispatch();

sleep(1);//死循环运行低级语句

}

结果和3同样

5:看到4,你可能会觉得,信号处理还是没有那么的智能,能不能不做死循环,就完成异步的信号接收并处理呢?在php7.1之后,有了新的信号处理函数:pcntl_async_signals,返回或设置是否异步信号处理:<?php

//文件一

echo getmypid();

pcntl_async_signals(true);//设置异步信号

pcntl_signal(SIGUSR1,function(){//安装个user1信号处理函数

echo "触发信号";

posix_kill(getmypid(),SIGSTOP);

});

posix_kill(getmypid(),SIGSTOP);//给进程发送暂停信号<?php

//文件2

posix_kill(文件1进程, SIGCONT);//给进程发送继续信号

posix_kill(文件1进程, SIGUSR1);//给进程发送user1信号

首先文件1运行,再给文件2运行之后,文件1的结果图:

71d287c4f4b383037ed3cd8595ac3e3f.png

文件1进程strace 命令截图:

df88d6088d1bb350e46803ac76c65861.png

可看到,进程休眠之后,被9271进程(文件2)唤醒之后并发送了siguse1信号,再然后输出了一段文字,再然后自己给自己发送了进程休眠信号,继续休眠

linux 查看进程命令.可看:

6:pcntl_alarm和创建一个计时器,在指定的秒数后向进程发送一个SIGALRM信号。每次对 pcntl_alarm()的调用都会取消之前设置的alarm信号。例如:<?php

pcntl_signal(SIGALRM, function () {

echo '定时到时' . PHP_EOL;

});

pcntl_alarm(5);

$i=0;

while(1){

echo $i.PHP_EOL;$i++;

pcntl_signal_dispatch();

sleep(1);

}

a99a5d4e76bd0cfa0662cb88a2d610f7.png

该函数使用场景之一:php熔断<?php

pcntl_async_signals(true);

pcntl_signal(SIGALRM, function () {

echo 'php处理超时' . PHP_EOL;

});

pcntl_alarm(30);

/*

* 这里是一大段php处理函数

* */

pcntl_alarm(-1);

先进行30秒的定时,当处理函数超过30秒时,将触发php处理超时函数,从而进行超时逻辑,当在30秒处理完毕时,php将关闭改定时信号,正常往下执行

三:其他

1:php进程信号中,无法捕获SIGKILL信号,该信号将会强制关闭进程

本文为仙士可原创文章,转载无需和我联系,但请注明来自仙士可博客www.php20.cn

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值