신호는 소프트 인터럽트, 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 |