不懂就问:kill -9主进程之后,主进程内的socket该如何回收?

最近做了一个进程管理,可是在自测的时候发现一个问题。那就是主进程在被kill -9子进程还存在的情况下,主进程的socket无法释放。再次重启脚本的时候就会提示错误如下:
PHP Warning: stream_socket_server(): unable to connect to tcp://0.0.0.0:7865 (Address already in use)。可是如果把原来的子进程都杀死就不会出现这个问题。可是这是为什么呢?

<?php
// 伪代码如下:
$stream = stream_socket_server($host, $errno, $errstr);
while(true) {
    // (1)管理子进程
    // (2)accept接收请求&&处理请求
    // (3)回收子进程
}
最佳答案

建议研究下 swoole 的进程管理,比自己写更可靠。
分析楼主问题的原因是子进程没有回收,地址被占用,因此报错。
多进程下需要设置地址和端口重用,

$connext_option=['socket'=>['backlog'=>10240, //等待处理连接的队列],];
$connext=stream_context_create($connext_option);
stream_context_set_option($connext,'socket','so_reuseaddr',1); //
stream_context_set_option($connext,'socket','so_reuseport',1); //
$main_sock=stream_socket_server($this->_sAddr,$errno,$errstr,STREAM_SERVER_BIND|STREAM_SERVER_LISTEN,$connext);

创建子进程后要有回收机制,防止子进程成为僵尸进程

$pid = pcntl_wait($status);

参考下
blog.csdn.net/yt_php/article/detai...
blog.csdn.net/yt_php/article/detai...

3年前 评论
so_easy (楼主) 3年前
so_easy (楼主) 3年前
php_yt (作者) 3年前
讨论数量: 2

建议研究下 swoole 的进程管理,比自己写更可靠。
分析楼主问题的原因是子进程没有回收,地址被占用,因此报错。
多进程下需要设置地址和端口重用,

$connext_option=['socket'=>['backlog'=>10240, //等待处理连接的队列],];
$connext=stream_context_create($connext_option);
stream_context_set_option($connext,'socket','so_reuseaddr',1); //
stream_context_set_option($connext,'socket','so_reuseport',1); //
$main_sock=stream_socket_server($this->_sAddr,$errno,$errstr,STREAM_SERVER_BIND|STREAM_SERVER_LISTEN,$connext);

创建子进程后要有回收机制,防止子进程成为僵尸进程

$pid = pcntl_wait($status);

参考下
blog.csdn.net/yt_php/article/detai...
blog.csdn.net/yt_php/article/detai...

3年前 评论
so_easy (楼主) 3年前
so_easy (楼主) 3年前
php_yt (作者) 3年前

因为你的socket是在主进程中生成的,子进程会共享这个socket,虽然当主进程被杀掉后,但因为子进程的存在,这个socket依然被占用没有得到释放,因此你重新执行脚本就会报错,杀掉所有子进程后,该socket就被释放了,再次执行脚本也就不会报错了。

你不应该这么暴力的直接使用kill -9来终止主进程,你应该使用进程信号机制,通知进程优雅的退出并释放资源。

3年前 评论
so_easy (楼主) 3年前
后后 (作者) 3年前
so_easy (楼主) 3年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!