Skip to content

Instantly share code, notes, and snippets.

@jacking75
Last active March 9, 2021 06:55
Show Gist options
  • Save jacking75/80a38f0d928b7c592863bdbb23a6fb7f to your computer and use it in GitHub Desktop.
Save jacking75/80a38f0d928b7c592863bdbb23a6fb7f to your computer and use it in GitHub Desktop.
//출처: https://github.com/phpsphb/book-examples/blob/master/multiprocess/limited_forking_echo_server.php
<?php
$server = stream_socket_server('tcp://127.0.0.1:'.(getenv('PORT') ?: 1234), $errno, $errstr);
if (false === $server) {
fwrite(STDERR, "Failed creating socket server: $errstr\n");
exit(1);
}
echo "Waiting…\n";
const MAX_PROCS = 2;
$children = [];
for (;;) {
$read = [$server];
$write = null;
$except = null;
stream_select($read, $write, $except, 0, 500);
foreach ($read as $stream) {
if ($stream === $server && count($children) < MAX_PROCS) {
$conn = @stream_socket_accept($server, -1, $peer);
if (!is_resource($conn)) {
continue;
}
echo "Starting a new child process for $peer\n";
//pcntl_fork의 반환 값은 부모 프로세스의 경우는 자식 프로세스의 PID, 자식 프로세스의 경우는 0, fork에 실패한 경우는 -1
$pid = pcntl_fork();
if ($pid > 0) {
$children[] = $pid;
} elseif ($pid === 0) {
// Child process, implement our echo server
$childPid = posix_getpid();
fwrite($conn, "You are connected to process $childPid\n");
while ($buf = fread($conn, 4096)) {
fwrite($conn, $buf);
}
fclose($conn);
// We are done, quit.
exit(0);
}
}
}
// Do housekeeping on exited childs
foreach ($children as $i => $child) {
//pcntl_waitpid는 종료한 자식 프로세스의 프로세스 ID를 반환한다.
//WNOHANG 옵션을 지정하면 자식 프로세스가 종료하지 않은 경우에 바로 처리를 반환한다
$result = pcntl_waitpid($child, $status, WNOHANG);
//pcntl_wifexited는 상태가 정상 종료했는지 조사한다
if ($result > 0 && pcntl_wifexited($status)) {
unset($children[$i]);
}
}
echo "\t".count($children)." connected\r";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment