php socket网络编程基础知识(四):多进程
2021-01-19 01:18
标签:status 传递 windows 返回 修改 队列 _for 响应 关联 这里涉及到一些linux系统相关的的概念,可能需要先做了解 PCNTL函数 POSIX函数 php socket网络编程基础知识(四):多进程 标签:status 传递 windows 返回 修改 队列 _for 响应 关联 原文地址:https://www.cnblogs.com/vishun/p/10490213.html说明
nginx
、php-fpm
帮我们处理好了,我们配置他们参数时就需要设置进程个数相关参数exec
相关的函数,所以并不是涉及到多进程都需要上方扩展,推荐symfony/process,对php此类相关函数进行的封装和兼容处理,同时支持linux和windows,非常好用的多进程库,一般的中小项目完全满足需求。概念
相关函数
pcntl_fork
( void ) : int
if
来判定哪个是父进程哪个是子进程。pcntl_wait
( int &$status [, int $options = 0 ] ) : int
pcntl_waitpid
( int $pid , int &$status [, int $options = 0 ] ) : int
pcntl_wait
基本一样,但是多了指定pid的参数,当$pid=-1时,相当于pcntl_wait
,其它的$pid参数自行查看文档$status
是个引用,可以获取到子进程结束时的状态信息,通过调用其它函数来解析status
具体含义WNOHANG
和WUNTRACED
。上面两个函数默认是阻塞的,直到有子进程结束时,才会有响应动作,如果想不阻塞,可以将$options参数设置为WNOHANG
,当没有子进程退出时不再阻塞等待,而是直接返回0,而如果设置为WUNTRACED
参数则和设置为0一样还是阻塞,但是除了子进程结束会响应外SIGTTIN
, SIGTTOU
, SIGTSTP
,SIGSTOP
这些信号也会响应。
posix_getpid
( void ) : int
posix_getppid
( void ) : int
posix_getuid
( void ) : int
posix_setuid
( int $uid ) : bool
posix_getgid
( void ) : int
posix_setgid
( int $gid ) : bool
posix_getsid
( int $pid ) : int
posix_getpid
获取pid参数,再获取sid
posix_getpwuid
( int $uid ) : array
posix_getpwnam
( string $username ) : array
posix_getgrgid
( int $gid ) : array
posix_getgrnam
( string $name ) : array
posix_initgroups
( string $name , int $base_group_id ) : bool
$name
所属的附加组也加入到此进程的组权限中。setgid
有些类似。用户是有附加组的,同一个用户可能属于多个组,setuid
只是设置用户ID,setgid
是设置组ID,但用户ID可能同时还有其它组的权限,要想获取其它组的权限,则需要运行此命令。相关代码
$pid = pcntl_fork();
//父进程和子进程都会执行下面代码
if ($pid == -1) {
//错误处理:创建子进程失败时返回-1.
die(‘could not fork‘);
} else if ($pid) {
//父进程会得到子进程号,所以这里是父进程执行的逻辑
pcntl_wait($status); //等待子进程中断,防止子进程成为僵尸进程。
} else {
//子进程得到的$pid为0, 所以这里是子进程执行的逻辑。
}
$user = ‘www‘;
$group = ‘www‘;
// Get uid.
$user_info = posix_getpwnam($user);
if (!$user_info) {
echo "Warning: User {$user} not exsits";
exit;
}
$uid = $user_info[‘uid‘];
// Get gid.
if ($group) {
$group_info = posix_getgrnam($group);
if (!$group_info) {
echo "Warning: Group {$group} not exsits";
exit;
}
$gid = $group_info[‘gid‘];
} else {
$gid = $user_info[‘gid‘];
}
// Set uid and gid.
if ($uid != posix_getuid() || $gid != posix_getgid()) {
if (!posix_setgid($gid) || !posix_initgroups($user_info[‘name‘], $gid) || !posix_setuid($uid)) {
echo "Warning: change gid or uid fail.";
exit;
}
}
需要注意
user:www www
,就是在指定子进程运行的用户名和用户组,否则子进程也用root来运行的话权限过大,存在安全隐患。
wait
或waitpid
来阻塞或者是循环来处理子进程回收SIGCHLD
来实现,每个子进程结束时都会发送SIGCHLD
信号,父进程进行捕捉调用wait
或waitpid
来回收SIGCHLD
来实现:signal(SIGCHLD, SIG_IGN)
,此时子进程结束时,直接由内核init进程来负责回收
上面几种方式看似第一种不太好,因为主进程都用来处理子进程的回收了,就不能做其它的事情了,但实际上主进程本来就是来管理子进程的,并没有多少自己的逻辑,而且越少处理逻辑越安全,所以直接在循环中处理并没有什么问题。关联
文章标题:php socket网络编程基础知识(四):多进程
文章链接:http://soscw.com/index.php/essay/43876.html