pcntl_exec 函数用来执行一个程序,它内部的系统调用是 execve
一般的用法是父进程先创建一个子进程,然后子进程调用这个函数,正文段(代码段)+ 数据段会被新程序替换,它的一些属性会继承父进程,PID并没有发生变化。
execve() executes the program referred to by pathname. This causes the program that is currently being run by the calling process to be replaced with a new program, with newly initialized stack, heap, and (initialized and uninitialized) data segments.
pathname must be either a binary executable, or a script starting with a line of the form:
#!interpreter [optional-arg]
——execve
示例:
demo7.php
<?php
function showID($str)
{
$pid = posix_getpid();
fprintf(
STDOUT,
"%s pid=%d,ppid=%d,gpid=%d,sid=%d,uid=%d,gid=%d\n",
$str,
$pid,
posix_getppid(),
posix_getpgrp(),
posix_getsid($pid),
posix_getuid(),
posix_getgid()
);
}
showID("parent:");
$pid = pcntl_fork();
if (0 == $pid) {
pcntl_exec('/usr/bin/php', ['demo2.php', 'a', 'b', 'c']);
echo "hello world"; // 不会执行,
}
$exitPid = pcntl_wait($status);
if ($exitPid > 0){
fprintf(STDOUT,"exit pid=%d\n",$exitPid);
}
demo2.php
<?php
function showID($str)
{
$pid = posix_getpid();
fprintf(
STDOUT,
"%s pid=%d,ppid=%d,gpid=%d,sid=%d,uid=%d,gid=%d\n",
$str,
$pid,
posix_getppid(),
posix_getpgrp(),
posix_getsid($pid),
posix_getuid(),
posix_getgid()
);
}
showId('child:');
运行结果:
$ php demo7.php
parent: pid=1465,ppid=59,gpid=1465,sid=59,uid=1000,gid=1000
child: pid=1466,ppid=1465,gpid=1465,sid=59,uid=1000,gid=1000
exit pid=1466
通过 strace -f -s 65500 -o demo7.log php demo7.php
查看系统调用:
2227 execve("/usr/bin/php", ["php", "demo7.php"], 0x7ffeba4701b0 /* 53 vars */) = 0
...
// 创建子进程
2227 clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f08921d7c50) = 2228
...
2227 getpid() = 2227
2227 getppid() = 2225
2227 getpgrp() = 2225
2227 getsid(2227) = 59
2227 getuid() = 1000
2227 getgid() = 1000
2227 write(1, "parent: pid=2227,ppid=2225,gpid=2225,sid=59,uid=1000,gid=1000\n", 62) = 62
// 运行 demo2.php
2228 execve("/usr/bin/php", ["/usr/bin/php", "demo2.php", "a", "b", "c"], 0x555801030e70 /* 53 vars */) = 0
...
2228 getpid() = 2228
2228 getppid() = 2227
2228 getpgrp() = 2225
2228 getsid(2228) = 59
2228 getuid() = 1000
2228 getgid() = 1000
2228 write(1, "child: pid=2228,ppid=2227,gpid=2225,sid=59,uid=1000,gid=1000\n", 61) = 61
...