개발 꿀팁/PHP

php 신호 처리

Jammie 2022. 9. 23. 12:48
반응형

신호는 소프트 인터럽트, ipc 통신 중 하나이며 유일한 비동기 통신 방식입니다.리눅스에서는 kill-l을 사용하여 시스템에서 지원되는 모든 신호를 볼 수 있습니다. 어떤 프로세스에 신호를 보낼 때는 kill-signal type pid를 사용하여 지정한 pid를 사용할 수 있습니다.php에서 우리는 신호 전송을 위해 posxi_kill을 사용합니다.

posix_kill이 프로세스에 신호를 보내는 몇 가지 역할:
1. 지정한 프로세스에 신호 보내기
posix_kill("프로세스 번호", 9)
2, 프로세스의 생존 여부를 감지하고, true를 반환하면 프로세스가 존재함을 나타내고, 그렇지 않으면 false를 반환합니다.
$res=posix_kill("프로세스 번호", 0);
3. 현재 프로세스 그룹에 신호를 보내고 9는 강제로 종료되며 물론 상수 SIGKILL, 0은 프로세스 그룹의 모든 프로세스를 나타내는 특수 프로세스입니다.
posix_kill(0,9);

php에서는 신호 처리를 사용하고, php5.3 이전에는 declare 문장을 사용하여 신호를 감지하고, demo1을 봅니다.

vim demo1
#!/usr/local/php/bin/php
<?php
 
declare(ticks = 1); 
pcntl_signal(SIGINT, function(){
	echo "신호 트리거\n";
});
 
$i=1;
while(true){
  $i++;
  echo $i,"\n";
  sleep(1);    
}

저장 종료 스크립트 실행 및 실행 가능 설정

chmod +x demo1 && ./demo1

이때 프로그램은 $i의 값을 계속 출력하고, 우리는 ctrl+c를 사용하여 현재 프로세스에 신호를 보내고, 출력 신호는 트리거되며, 신호를 인수하기 때문에 종료되지 않습니다.ctrl+\ 를 사용하여 강제 종료합니다

다음으로 두 번째 방식인 demo2를 pcntl_signal_dispatch 함수를 사용하여 구현한다

#!/usr/local/php/bin/php
<?php
pcntl_signal(SIGINT, function(){
    echo "신호 트리거\n";
});
 
$i=0;
while(true){
  pcntl_signal_dispatch();
  $i++;
  echo $i,"\n";
  sleep(1);    
}

테스트 방식도 마찬가지로 ctrl+c,ctrl+\이며, pcntl_signal_dispatch를 사용하면 tick보다 cpu가 적게 소모됩니다.

세 번째 방법, php7.1.0 이후, 새로운 함수 pcntl_async_signals를 추가하여 신호 처리를 실현한다, demo3

#!/usr/local/php/bin/php
<?php
 
pcntl_async_signals(true);
 
pcntl_signal(SIGINT, function(){
    echo "신호 트리거\n";
});
 
 
$i=0;
while(true){
  $i++;
  echo $i,"\n";
  sleep(1);    
}

테스트 방식도 마찬가지로 ctrl+c,ctrl+\이며, 비동기 신호의 방식으로 구현된다.php7.1.0은 아직 새것이기 때문에 호환을 위해 우리는 이렇게 demo4를 쓸 수 있다

#!/usr/local/php/bin/php
<?php
 
if(version_compare(PHP_VERSION, '7.1.0')>=0){
    pcntl_async_signals(true);
}
 
pcntl_signal(SIGINT, function(){
   echo "신호 트리거\n";
});
 
 
$i=0;
while(true){
    if(version_compare(PHP_VERSION, '7.1.0')<0){
        pcntl_signal_dispatch();
    }
    $i++;
    echo $i,"\n";
    sleep(1);    
}

여러 신호를 등록하는 예 1:

#!/usr/local/php/bin/php
<?php
 
class Test
{
    public function handler($sig)
    {
        echo "신호값:" . $sig . "신호 트리거\n";
    }
    public function run()
    {
        pcntl_async_signals(true);
        pcntl_signal(SIGINT, [ & $this, "handler"]);
        pcntl_signal(SIGUSR1, [ & $this, "handler"]);
        pcntl_signal(SIGUSR2, [ & $this, "handler"]);
    }
}
$p1 = new Test();
$p1->run();
 
$i = 0;
while (true) {
    $i++;
    echo $i, "\n";
    sleep(1);
}

물론 정적 클래스일 수도 있습니다

#!/usr/local/php/bin/php
<?php
class Test
{
    public static function handler($sig)
    {
        echo "신호값:" . $sig . "신호 트리거\n";
    }
 
    public static function run()
    {
        pcntl_async_signals(true);
        pcntl_signal(SIGINT, ['Test', "handler"]);
        pcntl_signal(SIGUSR1, ['Test', "handler"]);
        pcntl_signal(SIGUSR2, ['Test', "handler"]);
    }
}
 
Test::run();
 
$i = 0;
while (true) {
    $i++;
    echo $i, "\n";
    sleep(1);
}

 

반응형

'개발 꿀팁 > PHP' 카테고리의 다른 글

[php] 너 정말 트라이캐치 할 줄 알아?  (1) 2022.09.23
php 해석 yaml  (0) 2022.09.23
PHP에서 웹 페이지 건너뛰기 방법  (0) 2022.09.23
php 비교 부동 소수점 수  (0) 2022.09.22
php 작업MySQL(pdo)  (0) 2022.09.22