不废话,先上一段代码
<?php
error_reporting(7);
$serv = new swoole_server("0.0.0.0", 9500, SWOOLE_PROCESS);
$serv->set([
'worker_num' => 1,
'task_worker_num' => 1,
]);
$serv->on('Receive', function(swoole_server $server, $fd, $from_id, $data)
{
$server->task('a');
});
$serv->on('workerstart', function(swoole_server $server, $id)
{
});
//$serv->set([]);
$serv->on('Task', function($serv, $task_id, $from_id, $data)
{
$arr = ['a','b','c','d'];
$processes = [];
foreach ($arr as $v)
{
echo "-------". (microtime(1))."\n";
$process = new swoole_process(function(swoole_process $worker) use ($v)
{
echo $v."======". ($t = microtime(1))."\n";
sleep(3);
echo $v."++++++". (microtime(1) - $t)."\n";
// $worker->daemon(true);
}, false);
$process->start();
$processes[] = $process;
}
while(true)
{
# 等待回收,如果不回收进程会变成僵死进程,很可怕的
if (false === swoole_process::wait())
{
break;
}
}
echo "done\n";
});
$serv->on('Finish', function()
{
});
$serv->start();
error_reporting(7);
$serv = new swoole_server("0.0.0.0", 9500, SWOOLE_PROCESS);
$serv->set([
'worker_num' => 1,
'task_worker_num' => 1,
]);
$serv->on('Receive', function(swoole_server $server, $fd, $from_id, $data)
{
$server->task('a');
});
$serv->on('workerstart', function(swoole_server $server, $id)
{
});
//$serv->set([]);
$serv->on('Task', function($serv, $task_id, $from_id, $data)
{
$arr = ['a','b','c','d'];
$processes = [];
foreach ($arr as $v)
{
echo "-------". (microtime(1))."\n";
$process = new swoole_process(function(swoole_process $worker) use ($v)
{
echo $v."======". ($t = microtime(1))."\n";
sleep(3);
echo $v."++++++". (microtime(1) - $t)."\n";
// $worker->daemon(true);
}, false);
$process->start();
$processes[] = $process;
}
while(true)
{
# 等待回收,如果不回收进程会变成僵死进程,很可怕的
if (false === swoole_process::wait())
{
break;
}
}
echo "done\n";
});
$serv->on('Finish', function()
{
});
$serv->start();
(TO小白:保存成test.php文件,然后php test.php这样运行,再telnet 127.0.0.1 9500 上,随便输入个内容回车就可以执行了)
这个代码成功执行后,在控制台上会输出4个WARN的错误,类似
zm_deactivate_swoole: worker process is terminated by exit()/die().
经过测试发现,如果 new swoole_process 时第二个参数设置成 true(定向子进程的标准输入和输出),则不会报这样的错误。
但是我的程序就是需要接受输出那么怎么办呢?
在测试代码里有一个注释了的代码
// $worker->daemon(true);
,把注释去掉这样就解决了,不再报那个错误了。
daemon 方法可见文档,它是把子进程蜕变成一个守护进程用的。
最后,再强调一下,一定要:
while(true)
{
# 等待回收,如果不回收进程会变成僵死进程,很可怕的
if (false === swoole_process::wait())
{
break;
}
}
{
# 等待回收,如果不回收进程会变成僵死进程,很可怕的
if (false === swoole_process::wait())
{
break;
}
}
这样进行回收,因为测试代码里开了4个子进程,如果只回收1次,还会有3个进程得不到回收,变成僵死进程的。