PHP는 pcntl과 libevent를 사용하여 Timer 기능을 구현합니다. 먼저 pcntl(PHP 스레드)을 살펴보겠습니다.
<?php function newChild($func_name) { echo "enter newChild\n"; $args = func_get_args(); unset($args[0]); $pid = pcntl_fork(); if ($pid == 0) { function_exists($func_name) and exit(call_user_func_array($func_name, $args)) or exit(-1); } else if($pid == -1) { echo "Couldn't create child process"; } else { return $pid; } } (PS:^_^不错的php开发交流群:256271784,验证:csl,有兴趣的话可以加入进来一起讨论) function on_timer() { echo "timer called\n"; } /** * @param $func string, function name * @param $timeouts int, microtimes for time delay */ function timer($func, $timeouts){ echo "enter timer\n"; $base = event_base_new(); $event = event_new(); event_set($event, 0, EV_TIMEOUT, $func); event_base_set($event, $base); event_add($event, $timeouts); event_base_loop($base); } $pid = newChild("timer", "on_timer", 5000000); if ($pid > 0) { echo "master process exit\n"; }
PHP는 pcntl을 확장하여 "멀티 스레딩"(프로세스)
pcntl 및 틱
틱은 선언(틱스 = n) {statement} 구문을 통해 정의됩니다. 선언 구문은 현재 허용됩니다. 그가 정의한 Ticks = n의 의미는 선언으로 지정된 명령문 블록에서 N개의 하위 수준 명령문이 실행될 때 이 이벤트를 등록할 수 있다는 것입니다.
시그널 메커니즘 pcntl의 함수는 틱 메커니즘을 기반으로 구현되었습니다. 따라서 pcntl 함수 계열에서 신호 관련 함수를 사용할 때는 앞에 선언(ticks = n) 구문 구조를 추가해야 합니다.
int pcntl_alarm(int $ 초):
$seconds 초 역방향 프로세스 SIGALRM 신호를 보내고 pcntl_alarm 메소드를 호출할 때마다 이전에 설정된 시계가 취소됩니다.
void pcntl_exec(string $path[, array $args[, array $env] ]):
현재 프로세스 공간에서 프로그램을 실행합니다.
$path: 바이너리 실행 파일이거나 유효한 스크립트 헤더 정보가 있는 스크립트 파일 경로(#!/usr/local/bin/php) .
$args: 프로그램에 전달할 문자 String 매개변수 목록(배열 형태)
$envs: 환경변수. 실행될 프로그램의 환경변수에 배열 형태로 전달(key => 값 형식).
int pcntl_for k (void):
생성 PID(프로세스 번호) 및 PPID(상위 프로세스 번호)만 상위 프로세스와 다른 하위 프로세스를 반환합니다.
생성된 프로세스를 반환합니다. 상위 스레드가 실행될 때 하위 프로세스 pid가 생성되고 하위 스레드가 실행될 때 0이 반환됩니다. 생성 하위 프로세스가 실패하면 상위 프로세스 컨텍스트에서 -1이 반환되고 PHP 오류가 발생합니다.
포크를 이해하려면 여기에서 알아야 할 사항: pcntl_fork는 표시와 동일한 분기 노드를 생성합니다. 상위 프로세스가 완료된 후 하위 프로세스는 실행에서 시작됩니다. 표시에서 계속됩니다. 이는 pcntl_fork 이후의 코드가 두 번 실행됨을 의미합니다. 상위 프로세스와 하위 프로세스가 각각 실행 중 두 프로세스에서 얻는 반환 값이 다릅니다. 따라서 상위 프로세스와 하위 프로세스를 분리하여 서로 다른 코드를 실행할 수 있습니다.
int pcntl_getpriority([int $ pid = getmypid()[, int $process_identifier = PRIO_PROCESS]]):
주어진 $pid에 해당하는 프로세스의 우선순위를 가져옵니다. 기본값은 getmypid()를 통해 가져옵니다. 값은 현재 프로세스입니다.
$pid: 지정하지 않으면 기본값은 현재 프로세스입니다.
$process_identifier: PRIO_PGRP, PRIO_USER, PRIO_PROCESS 중 하나, 기본값은 PRIO_PROCESS입니다. 그 중 PRIO_PGRP는 프로세스 그룹을 가져오는 우선순위를 나타내며, PRIO_USER는 이를 참조합니다. 사용자 프로세스의 우선순위를 얻는다는 PRIO_PROCESS는 특정 프로세스의 우선순위를 얻는다는 의미입니다.
프로세스의 우선순위를 반환하거나, 오류가 발생하면 false를 반환합니다.
bool pcntl_setpriority(int $priority[ , int $pid = getmypid()[, int $process_identifier = PRIO_PROCESS]]:
프로세스의 우선순위를 설정합니다.
$priority: 우선순위 값, 범위 -20~ 20, 기본 우선순위는 0 입니다.
$pid: 지정하지 않으면 현재 프로세스를 나타냅니다.
$process_identifier: 의미는 pcntl_getpriority의 $process_identifier와 같습니다. .
설정이 성공하면 TRUE를 반환하고, 실패하면 FALSE를 반환합니다.
bool pcntl_signal_dispatch(void):
pcntl_signal()을 통해 설치된 다가오는 시그널의 핸들러를 호출합니다.
호출은 TRUE를 반환합니다. 성공하면 false, 실패하면 false.
php 5.3.3 추가
bool pcntl_signal(int $signo, callback $handler[, bool $restart_syscalls = true]):
새 신호 처리기 $handler를 설치합니다. 지정된 신호 $signo.
마지막 매개변수는 의미가 없습니다.
bool pcntl_sigprocmask (int $how, array $set[, array &$oldset]):
잠금 신호를 추가, 삭제 또는 설정합니다. 구체적인 동작은 $how 매개변수에 따라 다릅니다
$how: SIG_BLOCK은 현재 잠금에 신호를 추가하는 데 사용됩니다. 잠금 신호 중 SIG_UNBLOCK은 현재 잠금 신호에서 신호를 제거하는 데 사용되고 SIG_SETMASK는 현재 잠금을 대체하는 데 사용됩니다. 주어진 신호 목록으로 신호를 보냅니다.
$set: 추가, 제거 또는 설정할 신호 목록.
$oldset: 호출자에게 이전 잠금 신호를 반환하는 데 사용됩니다.
성공 시 TRUE를 반환합니다. 실패 시 FALSE.
int pcntl_sigtimedwait(array $set[, array &$siginfo[, int $seconds = 0[, int $nanoseconds = 0]]]):
pcntl_sigtimedwait는 실제로 pcntl_sigwaitinfo(와 동일한 작업을 수행합니다. ), 그러나 pcntl_sigtimedwait에는 $seconds 및 $nanoseconds라는 두 가지 향상된 매개변수가 있어 스크립트를 더 오래 유지할 수 있습니다. 무제한 대기 대신 상한이 있습니다.
$set: 기다려야 하는 신호 목록
$siginfo: 대기할 신호에 대한 정보를 호출자에게 반환하는 데 사용됩니다. 정보 내용은 pcntl_sigwaitinfo
$seconds: Timeout 초 수
$nanoseconds: 시간 초과에 대한 나노초 수
를 참조하세요. 성공 후 pcntl_sigtimedwiat()는 신호 번호를 반환합니다
int pcntl_sigwaitinfo(array $set[, array &$siginfo]):
Pending current $set의 신호 중 하나가 수신될 때까지 스크립트가 실행됩니다. 신호가 도착하려고 하면(예: pcntl_sigprocmask에 의해 잠긴 경우) pcntl_sigwaitinfo는 즉시
$set: 신호 대기 목록
$siginfo: 호출자에게 신호를 기다리는 신호 정보를 반환하는 데 사용됩니다. 여기에는 다음 내용이 포함됩니다.
1. 모든 신호에는 다음 세 가지 정보가 있습니다.
a) signo: 신호 번호
b) errno: 오류 번호
c) code: 신호 코드
2. SIGCHLD 신호별 정보
a) 상태: 종료 값 또는 신호
b) utime: 사용자 소비 시간
c) stime: 시스템 소비 시간
d) pid: 전송 프로세스 ID
e) uid: 전송 프로세스의 실제 사용자 ID
3. SIGILL, SIGFPE, SIGSEGV, SIGBUS
가 소유한 정보
a) addr: 오류가 발생한 메모리 위치
4. SIGPOLL 고유 정보:
a) 밴드: 밴드 이벤트, 의미를 알 수 없음
b) fd: 파일 설명자
함수가 성공적으로 실행되고 신호 번호를 반환합니다
int pcntl_wait(int &$status [ , int *options = 0]):
자식 프로세스가 종료될 때까지 또는 신호에서 현재 프로세스 종료를 요구하거나 호출 시 하위 프로세스가 이미 종료된 경우 신호 처리 함수가 호출될 때까지 현재 프로세스를 정지합니다. (일반적으로 좀비 프로세스라고 함) 이 함수는 즉시 반환되고 모든 시스템 리소스가 해제됩니다.
$status는 다음 함수에 의해 생성되는 하위 프로세스의 상태 정보를 저장하는 데 사용됩니다. pcntl_wifstopped, pcntl_wifsignaled, pcntl_wexitstatus, pcntl_wtermsig, pcntl_wstopsig .
$options: 시스템이 wait3(대부분의 BSD 유사 시스템)을 허용하는 경우 선택적 옵션 매개변수를 제공할 수 있습니다. 이 매개변수가 제공되지 않으면 wait는 시스템 호출을 사용합니다. 시스템이 wait3 을 허용하지 않는 경우 이 매개변수를 제공하면 아무런 효과가 없으며 $options 값은 0이거나 두 상수 WNOHANG 및 WUNTRACED일 수 있습니다.
이 함수는 종료하는 하위 프로세스의 PID를 반환하거나 -1을 반환합니다. 오류가 발생하거나, WNOHANG이 옵션으로 제공되고(wait3 시스템 불가) 유효한 자식 프로세스가 없는 경우 0을 반환합니다.
좀비 프로세스: 부모 프로세스가 포크 이후이므로 자식 프로세스가 언제 종료될지 예측이 불가능하므로 부모 프로세스에 일부 정보를 남기기 위해 자식 프로세스는 좀비라는 다음 데이터 구조를 떠나 부모 프로세스가 시작한 대기 작업이 시체를 수집할 때까지 기다립니다. 하위 프로세스의 종료(논리적 종료) 및 상위 프로세스에 의한 해당 시체 수집 종료 후 모든 하위 프로세스가 Init로 넘겨집니다. 따라서 상위 프로세스가 종료되면 좀비 프로세스가 재활용됩니다. 그러나 상위 프로세스가 종료되지 않으면 이러한 좀비 프로세스는 항상 프로세스 번호를 차지합니다. 시스템 프로세스 번호가 소진되면 새 프로세스를 시작할 수 없게 됩니다. 상위 프로세스에서 자체적으로 생성된 하위 프로세스의 시체를 수집합니다.
int pcntl_waitpid(int $pid, int &$status[, int $options = 0 ]):
하위 프로세스가 종료될 때까지 현재 프로세스를 정지합니다. 주어진 $pid를 가진 프로세스가 종료되거나, 현재 프로세스가 종료 신호를 받거나, 신호 처리기를 호출하기 위한 ige 신호를 받습니다.
$pid가 주어지면 이 함수를 호출할 때 해당 하위 프로세스가 종료(좀비 상태)되었습니다. , 함수는 즉시 반환되고 모든 시스템 리소스는 해제됩니다.
$pid: 프로세스 번호, -1 미만은 프로세스 그룹의 하위 프로세스를 기다리고 있음을 나타내며 프로세스 그룹 번호는 $의 절대값입니다. pid -1은 pcntl_wait 함수의 동작과 일치하여 자금성을 기다리는 것을 의미합니다. 0은 호출 프로세스와 동일한 그룹의 하위 프로세스를 기다리는 것을 의미하고 0보다 큰 것은 특정 프로세스를 의미합니다. .
$status: 함수에서 하위 프로세스 상태를 반환하는 데 사용됩니다. 이 상태 정보는 pcntl_wifexited, pcntl_wifstopped, pcntl_wifsignaled, pcntl_wexitstatus, pcntl_wtermsig, pcntl_wstopsig에 의해 생성됩니다.
$options: 동일한 의미를 갖습니다. as pcntl_wait's $options
int pcntl_wexitstat us (int $status):
중단된 하위 프로세스 반환 코드를 반환합니다. 이 함수는 pcntl_wifexited 함수가 TRUE를 반환하는 경우에만 유용합니다.
$status 매개변수는 상태 정보입니다. pcntl_waitpid에 의해 생성됩니다.
bool pcntl_wifexited(int $status):
주어진 상태가 하위 프로세스가 정상적으로 종료되었음을 나타내는지 확인합니다.
bool pcntl_wifsignaled(int $status):
주어진 상태가 특정 신호 수신으로 인해 하위 프로세스가 종료되었음을 나타냅니다.
bool pcntl_wifstopped(int $status):
$status가 하위 프로세스가 현재 중지되었음을 나타낼 수 있는지 확인하세요. 이 함수는 작업을 수행할 때만 $status를 생성합니다. $options 매개변수의 값으로 pcntl_waitpid 함수에서 사용되는 WUNTRACED 위에서만 유효합니다.
int pcntl_wstopsig(int $status):
$status를 분석하여 하위 프로세스를 중지하는 신호 수를 반환합니다. . 이 함수는 pcntl_wifsignaled가 TRUE를 반환하는 경우에만 유효합니다.
int pcntl_wtermsig(int $status):