pcntl_exec函数的作用以及用法

pcntl_exec()函数

  • 用途: 可能我们在编写php代码的时候会很少用到或者见到这个函数,但这个函数一般是用在运行脚本文件的时候才会使用,比如shell脚本,或者运行其他语言的脚本等等

  • 概念: PHP手册中的解释是在当前进程空间执行指定程序。

  • 使用: 根据文档,我们也能看到,他的第一个参数是一个可执行文件,或者解释器文件,第二个参数是一个数组,用来传递参数,当第一个参数是一个可执行文件的路径是,第二个参数的第一个数据则要传递你编写好的程序的路径,第三个参数则是环境变量。至于什么是解释器文件,大家可以看我之前写过的文章如何编写一个PHP解释器文件

编写代码--可执行文件

  • 编写一个PHP程序,用来打印pcntl_exec 中的第二个参数和第三个参数
<?php

/**
 * Created by PhpStorm
 * User: 北溟有鱼QAQ
 * Date: 2021-03-10
 * Time: 16:30
 * Email: 1769360227@qq.com
 */

print_r($argv)."\n";

print_r(getenv());
  • 编写测试程序
<?php

/**
 * Created by PhpStorm
 * User: 北溟有鱼QAQ
 * Date: 2021-03-10
 * Time: 16:08
 * Email: 1769360227@qq.com
 */


//打印当前父进程的进程id
echo "我是父进程的进程id".posix_getpid().PHP_EOL;

//调用pcntl_fork clone 一个子进程
$pid = pcntl_fork();

//当返回进程id是0的时候,则代表是子进程
if($pid === 0 )
{
    echo "我是子进程的进程id是".posix_getpid().PHP_EOL;
    // 第一个参数则是php可执行文件 第二个参数则是一个数组,数组的第一个元素则是要执行的程序
    pcntl_exec("/usr/bin/php",['test.php','aa','123'],['test']);
}
//子进程执行完成后,父进程要进行回收,如果不回收则会变成僵尸进程,占用系统资源
$exitId = pcntl_wait($status);

//返回退出进程的进程号
if($exitId > 0)
{
    echo "子进程退出成功,退出状态码是 ".pcntl_wexitstatus($status).PHP_EOL;
}
  • 执行代码,查看结果

我们会看到经过pcntl_exec函数,test.php 里面的代码也执行,这其实就是pcntl_exec的作用,用来执行一个程序

编写代码--解释器文件

  • 编写一个解释器文件,并给这个文件可执行权限
#! /usr/bin/php

<?php

print_r($argv)."\n";

print_r(getenv());

  • 复制之前的demo3代码并修改
/**
 * Created by PhpStorm
 * User: 北溟有鱼QAQ
 * Date: 2021-03-10
 * Time: 16:08
 * Email: 1769360227@qq.com
 */


//打印当前父进程的进程id
echo "我是父进程的进程id".posix_getpid().PHP_EOL;

//调用pcntl_fork clone 一个子进程
$pid = pcntl_fork();

//当返回进程id是0的时候,则代表是子进程
if($pid === 0 )
{
    echo "我是子进程的进程id是".posix_getpid().PHP_EOL;
    // 第一个参数则是php可执行文件 第二个参数则是一个数组,数组的第一个元素则是要执行的程序
    pcntl_exec("test",['aa','123'],['test']);
}
//子进程执行完成后,父进程要进行回收,如果不回收则会变成僵尸进程,占用系统资源
$exitId = pcntl_wait($status);

//返回退出进程的进程号
if($exitId > 0)
{
    echo "子进程退出成功,退出状态码是 ".pcntl_wexitstatus($status).PHP_EOL;
}
  • 再次执行,查看结果

  • 使用 strace -f -s 65500 -o demo4.log php demo4.php 命令来跟踪调用查看

总结

  • pcntl_exec函数其实是对linux api 中 execve的封装
  • pcntl_fork函数是对linux api 中 clone 的封装

北溟有鱼QAQ博客
请先登录后发表评论
  • 最新评论
  • 总共1条评论
北溟有鱼QAQ博客

鸡蛋羹:windows.location.href="https://xueyuanjun.com";

2021-03-11 11:54:42 回复