搜索
首页后端开发php教程PHP 使用pcntl和libevent 实现Timer功能

PHP 使用pcntl和libevent 实现Timer功能,先看例子,pcntl(PHP线程)解释在下面。

<?php  

function newChild($func_name) {  
    echo "enter newChild\n";  
    $args = func_get_args();  
    unset($args[0]);  
    $pid =  pcntl_fork();  
    if ($pid == 0) {  
        function_exists($func_name) and exit(call_user_func_array($func_name, $args)) or exit(-1);  
    } else if($pid == -1) {  
        echo "Couldn&#39;t create child process";  
    } else {  
        return $pid;  
    }  
}  

(PS:^_^不错的php开发交流群:256271784,验证:csl,有兴趣的话可以加入进来一起讨论)
function on_timer() {  
    echo "timer called\n";  
}  

   
/** 
 * @param $func string, function name 
 * @param $timeouts int, microtimes for time delay 
 */ 
function timer($func, $timeouts){  

   
    echo "enter timer\n";  
    $base = event_base_new();  
    $event = event_new();  

   
    event_set($event, 0, EV_TIMEOUT, $func);  
    event_base_set($event, $base);  
    event_add($event, $timeouts);  

   
    event_base_loop($base);  
}  

   
$pid = newChild("timer", "on_timer", 5000000);  

   
if ($pid > 0) {  
    echo "master process exit\n";  
}

PHP 扩展pcntl 实现 ” 多线程 ”( 进程 )
pcntl 与 ticks
ticks 是通过 declare(ticks = n) {statement} 语法定义的 , declare 语法目前只能接受 ticks, 他定义的 ticks = n 的意义是当 declare 指定的语句块中执行了 N 条低级语句去发生一个事件 , 这个事件可以通过 register_tick_function($function_name) 来注册 .
pcntl 的信号机制是基于 ticks 机制实现的 . 因此 , 我们使用 pcntl 族函数中信号相关的函数时 , 需要在前面增加 declare(ticks = n) 语法结构 .
int pcntl_alarm(int $seconds):
$seconds 秒后向进程发送一个 SIGALRM 信号 , 每次调用 pcntl_alarm 方法都会取消之前设置的时钟 .
void pcntl_exec(string $path[, array $args[, array $env]]):
在当前进程空间执行一个程序 .
$path: 必须是二进制可执行文件 , 或具有有效脚本头信息 (#!/usr/local/bin/php) 的脚本文件路径 .
$args: 将要传递给该程序的字符串参数列表 ( 数组形式 )
$envs: 环境变量 . 以数组 (key => value 形式 ) 方式传递给要执行程序的环境变量 .
int pcntl_for k (void):
创建一个子进程 , 该子进程与父进程仅仅是 PID( 进程号 ) 和 PPID( 父进程号 ) 不同 .
在父线程执行时返回创建的子进程 pid, 在子线程执行时返回 0, 创建子进程失败时会在父进程上下文返回 -1, 并引发 php 错误 .
理解这里的 fork 需要知道 : pcntl_fork 创建的是一个分支节点 , 相当于一个标记 , 父进程完成后 , 子进程会从标记处继续执行 , 也就是说 pcntl_fork 后面的代码分别被父进程和子进程执行了两遍 , 而两个进程在执行过程中得到的返回值是不同的 . 因此 , 才可以分离父子进程执行不同的代码 .
int pcntl_getpriority([int $pid = getmypid()[, int $process_identifier = PRIO_PROCESS]]):
获取给定 $pid 对应的进程的优先级 , 默认是通过 getmypid() 获取到的值也就是当前进程 .
$pid: 如果没有指定 , 默认是当前进程 .
$process_identifier: PRIO_PGRP, PRIO_USER, PRIO_PROCESS 三者之一 , 默认 PRIO_PROCESS. 其中 PRIO_PGRP 指获取进程组的优先级 , PRIO_USER 指获取用户进程的优先级 , PRIO_PROCESS 指获取特定进程优先级 .
返回进程的优先级 , 或者在发生错误时返回 false, 值越小说明越优先
bool pcntl_setpriority(int $priority[, int $pid = getmypid()[, int $process_identifier = PRIO_PROCESS]]:
设置进程的优先级 .
$priority: 优先级值 , -20 到 20 的范围内 , 默认优先级为 0.   值越小说明越优先 .
$pid: 如果没有指定 , 指当前进程
$process_identifier: 意义同 pcntl_getpriority 的 $process_identifier.
设置成功返回 TRUE, 失败返回 FALSE.
bool pcntl_signal_dispatch(void):
调用通过 pcntl_signal() 安装的即将发生的信号的处理器 .
调用成功返回 TRUE, 失败返回 false.
php 5.3.3 加入
bool pcntl_signal(int $signo, callback $handler[, bool $restart_syscalls = true]):
为指定的信号 $signo 安装一个新的信号处理器 $handler.
最后一个参数不明白意义 .
bool pcntl_sigprocmask(int $how, array $set[, array &$oldset]):
增加 , 删除或设置锁信号 , 具体的行为依赖于 $how 参数
$how: SIG_BLOCK 用于把信号增加到当前锁信号中 , SIG_UNBLOCK 用于把信号从当前锁信号中移除 , SIG_SETMASK 用于用给定的信号列表替换当前锁信号 .
$set: 要增加 , 移除或设置的信号列表 .
$oldset: 用于向调用者返回旧的锁定信号 .
成功返回 TRUE, 失败返回 FALSE.
int pcntl_sigtimedwait(array $set[, array &$siginfo[, int $seconds = 0[, int $nanoseconds = 0]]]):
pcntl_sigtimedwait 实际上和 pcntl_sigwaitinfo() 所做的是同样的事情 , 不过 pcntl_sigtimedwait 多了两个增强的参数 $seconds 和 $nanoseconds, 这样就允许脚本的停留时间有一个上限而不是无限制等待 .
$set: 需要等待的信号列表
$siginfo: 用来向调用者返回等待得到的信号的信息 , 信息内容见 pcntl_sigwaitinfo
$seconds: 超时的秒数
$nanoseconds: 超时的纳秒数
成功后 , pcntl_sigtimedwiat() 返回信号编号
int pcntl_sigwaitinfo(array $set[, array &$siginfo]):
挂起当前脚本的执行 , 直到接受到 $set 中的某个信号 , 如果其中的一个信号将要到达 ( 比如被 pcntl_sigprocmask 锁定 ) 那么 pcntl_sigwaitinfo 将会立刻返回
$set: 等待的信号列表
$siginfo: 用来向调用者返回等待得到的信号的信息 , 该信息包含以下内容 :
1.       所有信号都有以下三个信息 :
a)        signo: 信号编号
b)        errno: 错误号
c)         code: 信号代码
2.       SIGCHLD 信号特有的信息
a)        status: 退出的值或信号
b)        utime: 用户消耗时间
c)         stime: 系统消耗时间
d)        pid: 发送进程 id
e)        uid: 发送进程的真实用户 id
3.       SIGILL, SIGFPE, SIGSEGV, SIGBUS 拥有的信息
a)        addr: 产生故障的内存位置
4.       SIGPOLL 特有的信息 :
a)        band: band event, 意义未知
b)        fd: 文件描述符
函数成功运行返回信号编号
int pcntl_wait(int &$status[, int *options = 0]):
挂起当前进程直到一个子进程退出或直到一个信号要求终止当前进程或调用一个信号处理函数 . 如果子进程在调用时已经退出 ( 俗称成为了僵尸进程 ), 此函数会马上返回 , 所有的系统资源都将被释放 .
$status 用来保存子进程的状态信息 , 该状态信息由以下函数产生 : pcntl_wifexited, pcntl_wifstopped, pcntl_wifsignaled, pcntl_wexitstatus, pcntl_wtermsig, pcntl_wstopsig.
$options: 如果你的系统允许 wait3( 大多数的 BSD 类系统 ), 你可以提供一个可选的 options 参数 , 如果不提供这个参数 , wait 将会使用系统调用 , 如果系统不允许 wait3, 提供这个参数不会有任何影响 , $options 的值可以是 0 或者 WNOHANG 和 WUNTRACED 两个常数 .
函数返回退出的子进程的 PID, 或在错误时返回 -1, 或者如果提供 WNOHANG 作为 option(wait3 不可用的系统 ) 并且无有效子进程返回 0
僵尸进程 : 由于父进程在 fork 之后 , 无法预知子进程什么时候结束 , 所以子进程为了要留给父进程一些信息 , 会留下一个称作僵尸的数据结构 , 等待由父进程发起 wait 的操作来为它收尸 , 在子进程结束 ( 逻辑结束 ) 到父进程收尸前这一段时间子进程就被称为僵尸进程 , 在父进程结束后 , 所有的子进程会交由 Init 来负责 , 因此 , 如果父进程结束 , 僵尸进程都会被回收 , 但是 , 如果父进程永远不结束 , 这些僵尸进程就一直占用进程号 , 如果系统进程号耗尽 , 那么将导致无法启动新进程 , 因此 , 安全的做法是在父进程中为自己产生的子进程去收尸 .
int pcntl_waitpid(int $pid, int &$status[, int $options = 0]):
挂起当前进程直到给定 $pid 的子进程退出 , 或者当前进程接受到一个退出信号 , 或者接受到一 ige 信号去调用一个信号处理器 .
如果给定 $pid 对应的子进程在调用此函数时已经退出 ( 僵尸态 ), 函数立刻返回 , 所有的系统资源被释放 .
$pid: 进程号 , 小于 -1 表明等待的是进程组中的任何子进程 , 进程组号就是 $pid 的绝对值 . 等于 -1 表明等待任意紫禁城 , 与 pcntl_wait 函数行为一致 . 等于 0 代表等待与调用进程在同一组的子进程 , 大于 0 代表是特定的进程 .
$status: 用来由函数返回子进程状态 . 该状态信息由以下函数产生 : pcntl_wifexited, pcntl_wifstopped, pcntl_wifsignaled, pcntl_wexitstatus, pcntl_wtermsig, pcntl_wstopsig.
$options: 与 pcntl_wait 的 $options 意义相同
int pcntl_wexitstatus(int $status):
返回一个已经中断的子进程返回代码 , 此函数仅在 pcntl_wifexited 函数返回 TRUE 时有用 .
$status 参数是 pcntl_waitpid 产生的状态信息 .
bool pcntl_wifexited(int $status):
检查给定状态是否表明子进程是正常退出的 .
bool pcntl_wifsignaled(int $status):
检查给定状态是否表明子进程是由于收到某个信号退出的 .
bool pcntl_wifstopped(int $status):
检查 $status 是否能表明子进程当前已经停止 , 这个函数只有在作用于 pcntl_waitpid 函数使用的 WUNTRACED 作为 $options 参数的值时产生的 $status 上才有效 .
int pcntl_wstopsig(int $status):
通过分析 $status 返回使得子进程停止的信号的编号 , 这个函数只有在 pcntl_wifsignaled 返回 TRUE 时才有效 .
int pcntl_wtermsig(int $status):
返回使进程中断的信号编号 . 这个函数只有在 pcntl_wifsignaled 返回 TRUE 时才有效 .

更多PHP 使用pcntl和libevent 实现Timer功能相关文章请关注PHP中文网!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
PHP如何识别用户的会话?PHP如何识别用户的会话?May 01, 2025 am 12:23 AM

phpientifiesauser'ssessionusessessionSessionCookiesAndSessionIds.1)whiwSession_start()被称为,phpgeneratesainiquesesesessionIdStoredInacookInAcookInamedInAcienamedphpsessidontheuser'sbrowser'sbrowser.2)thisIdAllowSphptptpptpptpptpptortoreTessessionDataAfromtheserverMtheserver。

确保PHP会议的一些最佳实践是什么?确保PHP会议的一些最佳实践是什么?May 01, 2025 am 12:22 AM

PHP会话的安全可以通过以下措施实现:1.使用session_regenerate_id()在用户登录或重要操作时重新生成会话ID。2.通过HTTPS协议加密传输会话ID。3.使用session_save_path()指定安全目录存储会话数据,并正确设置权限。

PHP会话文件默认存储在哪里?PHP会话文件默认存储在哪里?May 01, 2025 am 12:15 AM

phpsessionFilesArestoredIntheDirectorySpecifiedBysession.save_path,通常是/tmponunix-likesystemsorc:\ windows \ windows \ temponwindows.tocustomizethis:tocustomizEthis:1)useession_save_save_save_path_path()

您如何从PHP会话中检索数据?您如何从PHP会话中检索数据?May 01, 2025 am 12:11 AM

ToretrievedatafromaPHPsession,startthesessionwithsession_start()andaccessvariablesinthe$_SESSIONarray.Forexample:1)Startthesession:session_start().2)Retrievedata:$username=$_SESSION['username'];echo"Welcome,".$username;.Sessionsareserver-si

您如何使用会议来实施购物车?您如何使用会议来实施购物车?May 01, 2025 am 12:10 AM

利用会话构建高效购物车系统的步骤包括:1)理解会话的定义与作用,会话是服务器端的存储机制,用于跨请求维护用户状态;2)实现基本的会话管理,如添加商品到购物车;3)扩展到高级用法,支持商品数量管理和删除;4)优化性能和安全性,通过持久化会话数据和使用安全的会话标识符。

您如何在PHP中创建和使用接口?您如何在PHP中创建和使用接口?Apr 30, 2025 pm 03:40 PM

本文解释了如何创建,实施和使用PHP中的接口,重点关注其对代码组织和可维护性的好处。

crypt()和password_hash()有什么区别?crypt()和password_hash()有什么区别?Apr 30, 2025 pm 03:39 PM

本文讨论了PHP中的crypt()和password_hash()之间的差异,以进行密码哈希,重点介绍其实施,安全性和对现代Web应用程序的适用性。

如何防止PHP中的跨站点脚本(XSS)?如何防止PHP中的跨站点脚本(XSS)?Apr 30, 2025 pm 03:38 PM

文章讨论了通过输入验证,输出编码以及使用OWASP ESAPI和HTML净化器之类的工具来防止PHP中的跨站点脚本(XSS)。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器