实现了Unix方式的进程创建, 程序执行, 信号处理以及进程的中断。 进程控制不能被应用在Web服务器环境,当其被用于Web服务环境时可能会带来意外的结果。使用了ticks作为信号处理的回调机制,ticks在速度上远远超过了之前的处理机制,使用declare() 语句在程序中指定允许发生回调的位置。这使得我们对异步事件处理的开销最小化。在编译PHP时 启用pcntl将始终承担这种开销,不论您的脚本中是否真正使用了pcntl
Windows平台上不可用,非Unix类系统不支持此模块
需要使用 --enable-pcntl配置选项重新编译PHP的CGI或CLI版本以打开进程控制支持
linux信号
[
SIGHUP => 1, // 终端连接断开信号
SIGINT => 2, // 中断信号,终端中输入ctrl+c,中断前台进程
SIGQUIT => 3, // 退出信号,终端中输入ctrl+\,退出前台进程,同时产生core文件
SIGTRAP => 5, // 调试信号,当在程序中设置断点后,该信号使得调试程序获得控制权
SIGABRT => 6, // 程序异常终止信号,abort函数产生该信号
SIGKILL => 9, // 杀死任意一个运行中的进程
SIGUSR1 => 10, // 用户自定义1
SIGUSR2 => 12, // 用户自定义2
SIGPIPE => 13, // 写入已关闭读端的管道产生该信号
SIGALRM => 14, // 定时器超时
SIGTERM => 15, // 终止程序信号,命令kill默认使用该参数
SIGCHLD => 17, // 子进程终止或停止时,产生该信号,默认被忽略
SIGTSTP => 20, // ctrl+z产生该信号,前台进程挂起
]
创建进程
// 创建一个子进程,这个子进程仅PID(进程号)和PPID(父进程号)与其父进程不同
// 成功时在父进程执行线程内返回产生的子进程的PID,在子进程执行线程内返回0。失败时在父进程返回-1,不会创建子进程,并会引发一个PHP错误
pcntl_fork();
设置/获取进程优先级
$process_identifiers = [
PRIO_PGRP, // 获取进程组优先级
PRIO_USER, // 获取用户进程优先级
PRIO_PROCESS, // 获取进程优先级,默认值
];
// 设置进程$pid的优先级为$priority(-20至20,默认0,越小优先级越高)
pcntl_setpriority($priority, $pid = getmypid(), $process_identifier = PRIO_PROCESS);
// 获取进程$pid的优先级
pcntl_getpriority($pid = getmypid(), $process_identifier = PRIO_PROCESS);
执行程序
// 在当前进程空间执行指定程序文件$path,发生错误时返回false;程序的参数为数组$args的键值对,环境变量为数组$envs的键值对
pcntl_exec($path, $args, $envs);
$options = [
WNOHANG, // 如果没有子进程退出立刻返回。
WUNTRACED, // 子进程已经退出并且其状态未报告时返回。
];
// 挂起当前进程的执行直到一个子进程退出或接收到一个信号要求中断当前进程或调用一个信号处理函数
// 如果一个子进程在调用此函数时已经退出(俗称僵尸进程),此函数立刻返回。子进程使用的所有系统资源将被释放
// 返回退出的子进程进程号,发生错误时返回-1,没有可用子进程时返回0
// 状态信息存储在$status上,使用pcntl_wifexited(), pcntl_wifstopped(), pcntl_wifsignaled(), pcntl_wexitstatus(), pcntl_wtermsig()以及 pcntl_wstopsig()可以获取其具体的值
pcntl_wait($status, $option = 0);
// 挂起当前进程的执行直到进程$pid退出或接收到一个信号要求中断当前进程或调用一个信号处理函数
// 如果进程$pid在此函数调用时已经退出(俗称僵尸进程),此函数将立刻返回
// $pid <-1时等待任意进程组ID等于参数pid给定值的绝对值的进程;等于-1时等待任意子进程,与pcntl_wait函数行为一致;等于0时等待任意与调用进程组ID相同的子进程;大于0时等待进程号等于参数pid值的子进程
// 状态信息存储在$status上,使用pcntl_wifexited(), pcntl_wifstopped(), pcntl_wifsignaled(), pcntl_wexitstatus(), pcntl_wtermsig()以及 pcntl_wstopsig()可以获取其具体的值
pcntl_waitpid($pid, $status, $option = 0);
// 暂停调用脚本的执行直到接收数组$set中的其中一个信号,只要信号已经在等待状态就立刻返回;$siginfo为信号的信息
pcntl_sigwaitinfo($set, $siginfo);
计时器
// 创建一个计时器,在指定的秒数$seconds后向进程发送一个SIGALRM信号。每次对pcntl_alarm()的调用都会取消之前设置的alarm信号。如果seconds设置为0,将不会创建alarm信号
pcntl_alarm($seconds);
信号处理
// $on为true启用异步信号处理,为null返回是否启用了异步信号处理的布尔值
pcntl_async_signals($on);
// 给信息$signo指定一个回调$handler;$handler可以为SIG_IGN(忽略信号处理程序)或SIG_DFL(默认信号处理程序)或自定义函数,函数只有在启用了异步信号处理才会被调用
pcntl_signal($signo, $handler);
// 获取信号$signo的回调函数,返回SIG_DFL或SIG_IGN的整数值或自定义函数名称
pcntl_signal_get_handler($signo);
// 调用等待信号的处理器
pcntl_signal_dispatch();
$hows = [
SIG_BLOCK, // 把信号加入到当前阻塞信号中。
SIG_UNBLOCK, // 从当前阻塞信号中移出信号。
SIG_SETMASK, // 用给定的信号列表替换当前阻塞信号列表
];
// 根据$how的指示增加、删除、设置阻塞信号$set(信号数组),之前的信号列表将存储在$oldset中
pcntl_sigprocmask($how, $set, $oldset);
// 设置等待信号数组$set,收到$set中任意一个信号后将继续脚本执行,此函数就会返回一个信号编号;$siginfo为信号的信息
pcntl_sigwaitinfo($set, $siginfo);
// 设置等待信号数组$set,等待信息号将有一个时间上限$seconds秒$nanoseconds纳秒,此函数会返回一个信号编号;$siginfo为信号的信息
pcntl_sigtimedwait($set, $siginfo, $seconds, $nanoseconds);
检查进程
// 检查子进程状态码$status(pcntl_waitpid()成功时提供的状态参数)是否代表正常退出
pcntl_wifexited($status);
// 检查子进程状态码$status(pcntl_waitpid()成功时提供的状态参数)是由于某个未捕获的信号退出的
pcntl_wifsignaled($status);
// 检查子进程状态码$status(pcntl_waitpid()成功时提供的状态参数)当前是否停止
// 此函数只有作用于使用了WUNTRACED作为option的pcntl_waitpid()函数调用产生的status时才有效。
pcntl_wifstopped($status);
获取错误
// 获取pcntl函数最后一个错误号
pcntl_get_last_error();
// 获取错误号$errno的错误信息
pcntl_strerror($errno);
获取进程中断信息
// 返回导致子进程停止的信号编号;$status为pcntl_waitpid()成功时提供的状态参数
pcntl_wstopsig($status);
// 返回导致子进程中断的信号编号;$status为pcntl_waitpid()成功时提供的状态参数
pcntl_wtermsig($status);
// 返回一个中断的子进程的返回代码;$status为pcntl_waitpid()成功时提供的状态参数
pcntl_wexitstatus($status);