첫 번째 방법은 nohup과 & 을 이용하여 사용합니다.
시작 프로세스를 백그라운드로 이동하기 위해 명령 뒤에 & 기호를 붙입니다콘솔을 사용하지 않고 실행하며, 다른 명령을 실행할 수 있습니다. 여기서 while 데드 루프를 사용하여 프레젠테이션을 합니다. 코드는 다음과 같습니다
<?php
while(true){
echo time().PHP_EOL;
sleep(3);
}
프로세스를 시작하기( N)
[root@localhost php]# php deadloop.php &
[1] 3454
[root@localhost php]# ps aux | grep 3454
root 3454 0.0 0.8 284544 8452 pts/0 T 18:06 0:00 php deadloop.php
root 3456 0.0 0.0 103316 896 pts/0 S+ 18:08 0:00 grep 3454
[1]+ Stopped php deadloop.php
[root@localhost php]#
이 프로세스가 콘솔을 사용하지 않고 다른 명령을 실행할 수 있는 것을 볼 수 있습니다. 이 경우 fg 명령을 사용하여 일반 콘솔 모드로 되돌릴 수 있습니다
[root@localhost php]# fg
php deadloop.php
1470996682
1470996685
1470996688
1470996691
이상 & 명령어에 대한 간단한 소개였습니다.
이제 또 다른 명령어 nohup
명령 앞에 nohup, 시작활성 프로세스가 리눅스의 보류 메시지를 무시합니다기호(SIGHUP), 어떤 경우에 Linux에서 SIGHUP 신호를 발생시키는지, 아래 내용은 바이두 백과에서 발췌한 것입니다.
SIGHUP은 다음과 같은 3가지 상황에서해당하는 프로세스로 보내기:
1.단말기가 꺼졌을 때 그 신호가 s로 전송됨ession 첫 번째 프로세스와 job으로 제시제출하는 프로세스 (예: 심볼로 제출하는 프로세스)
2. session 첫 번째 프로세스가 종료될 때,이 신호는 이 세션으로 보내집니다.프런트 데스크 프로세스 그룹의 모든 프로세스
3. 부모 프로세스가 종료되어 프로세스가 고립된 경우프로세스가 중지된 하위 프로세스 그룹정지 상태(SIGSTOP 또는 SIGTSTP 신호를 수신함) 이 신호는 프로세스 그룹의 모든 프로세스로 전송됩니다.
1과 2를 합치면 우리는 안다, 그렇지 않아도 알 수 있다.& (job) 방식으로 시작하는 프로세스입니다.터미널을 닫을 때 SIGHUP 신호가 수신됩니다. 그러면 프로세스에서 SIGHUP 신호가 수신되면 어떻게 됩니까? 역시 바이두 백과에서 발췌한 것입니다.
SIGHUP 신호에 대한 시스템 기본 처리이 신호를 받는 과정을 종료하는 것이다.따라서 프로그램이 이 신호를 포착하지 못하면 수신되면 프로세스가 종료된다.
즉, 터미널 프로세스를 종료하면 SIG가 수신됩니다.HUP 신호, 이 신호의 기본 처리 방식프로세스가 종료되면, 물론 이 신호를 캡처하여 처리하거나 무시할 수 있습니다. 예를 들어 다음 코드입니다.
<?php
pcntl_signal(SIGHUP, function(){
// 여기서 신호를 처리하는 방식은 우리는 단지 일지를 파일에 쓰는 것뿐이다
file_put_contents('logs.txt', 'pid : ' . posix_getpid() . ' receive SIGHUP 신호' . PHP_EOL);
});
while(1) {
sleep(10);
pcntl_signal_dispatch();
}
이 루틴을 명령줄에서 실행한 다음 셸 터미널 창을 닫은 다음 터미널을 다시 열어서 프로세스가 실행 중인지 확인합니다
[root@localhost php]# ps -ef | grep deadloop.php
root 16112 1 0 17:20 ? 00:00:00 php deadloop.php
root 16138 16115 0 17:24 pts/4 00:00:00 grep deadloop.php
[root@localhost php]# cat logs.txt
pid : 16112 receive SIGHUP신호
deadloop.php가 실행 중이고 부모 프로세스가 init 프로세스가 되고 (원래 부모 프로세스가 종료되어 init 프로세스에 의해 입양됨) 파일 내용에서 터미널 프로세스를 종료하는 것이 SIGHUP 신호를 받는 것을 볼 수 있습니다.사실 우리는 리눅스에서 제공하는 nohup 명령만 사용할 필요는 없지만, nohup을 사용하여 프로세스를 시작할 때 프로세스는 수신된 SIGHUP 신호를 무시하고 실행하지 않습니다. 먼저 이전 신호 처리 코드를 제거합니다.그리고 nohup 실행.
[root@localhost php]# nohup php deadloop.php
nohup: 입력 무시 및 출력 추가"nohup.out"
또한 nohup은 기본적으로 프로그램의 출력을 현재 디렉터리에 있는 nohup.out 파일로 리디렉션하며, 쓰기 권한이 없으면 $homepath/nohup.out에 기록합니다
[root@localhost php]# ls
cmd.sh deadloop.php getPhoto.php nohup.out pics
[root@localhost php]# tail -f nohup.out
1470999772
1470999775
1470999778
1470999781
1470999784
1470999787
1470999790
1470999793
1470999796
1470999799
1470999802
이때 단말기를 닫으면 프로세스가 종료되지 않고 고아 프로세스(ppid=1)가 되며, 이를 만든 부모 프로세스가 종료되기 때문이다
[root@localhost ~]# ps -ef | grep 3554
root 3554 3497 0 19:09 pts/0 00:00:00 php deadloop.php
root 3575 3557 0 19:10 pts/1 00:00:00 grep 3554
[root@localhost ~]# ps -ef | grep 3554
root 3554 1 0 19:09 ? 00:00:00 php deadloop.php
root 3577 3557 0 19:10 pts/1 00:00:00 grep 3554
[root@localhost ~]#
결론: 그래서 우리가 nohup과 & 을 조합할 때 부팅되는 프로세스가 콘솔을 차지하거나 의존하지 않고 콘솔이 닫히면 프로세스가 1번 프로세스에 의해 입양되어 고아 프로세스가 되는 것이 데몬의 메커니즘과 매우 유사합니다
[root@localhost php]# nohup php deadloop.php >logs.txt 2>error.txt &
[1] 3612
[root@localhost php]# ps -ef |grep 3612
root 3612 3557 0 19:18 pts/1 00:00:00 php deadloop.php
root 3617 3557 0 19:19 pts/1 00:00:00 grep 3612
[root@localhost php]#
이 중 >logs.txt 표준 출력 재연결, 2 >error.txt 표준 출력 재연결 오류.
첫 번째 실현방식에 대한 소개입니다.
두 번째 구현방식은 데몬의 규칙과 특징에 따라 코드로 구현되며 데몬의 가장 큰 특징은 탈사용입니다.사용자 단말기와 세션, 다음은 구현 코드, 키지방에서 주석을 달았다
<?php
$pid = pcntl_fork();
if ($pid == -1)
{
throw new Exception('fork 하위 프로세스 실패');
}
elseif ($pid > 0)
{
//상위 프로세스가 종료되었습니다. 하위 프로세스가 프로세스 팀장이 아니므로 새 세션을 쉽게 만들 수 있습니다
exit(0);
}
//가장 중요한 단계, 새 세션을 만들고 원래 제어 터미널에서 벗어나십시오
posix_setsid();
// 현재 프로세스의 작업 디렉터리를 수정합니다. 하위 프로세스가 상위 프로세스의 작업 디렉터리를 상속하기 때문에 상위 프로세스의 작업 디렉터리에 대한 사용 권한을 해제하도록 작업 디렉터리를 수정합니다
chdir('/');
/*
* 이전 단계를 통해 세션 팀장, 프로세스 팀장을 새로 만들고 터미널에서 벗어났지만 세션 팀장은 터미널을 다시 열지 못하도록 요청할 수 있습니다
* 이 경우 하위 프로세스를 다시 만들고 현재 프로세스를 종료합니다. 그러면 실행 중인 프로세스가 세션 팀장이 되지 않습니다。
*/
$pid = pcntl_fork();
if ($pid == -1)
{
throw new Exception('fork 하위 프로세스 실패');
}
elseif ($pid > 0)
{
//상위 프로세스를 다시 종료합니다. 하위 프로세스가 최종 데몬이 됩니다
exit(0);
}
// 데몬이 표준 I/O를 사용할 수 없기 때문에 표준 I/O, 출력 설명자 오류
fclose(STDIN);
fclose(STDOUT);
fclose(STDERR);
/*
* 업무 코드 처리
*/
while(TRUE)
{
file_put_contents('log.txt', time().PHP_EOL, FILE_APPEND);
sleep(5);
}
That's all!
'개발 꿀팁 > PHP' 카테고리의 다른 글
ecshop 취약성 복구 정리 (0) | 2022.07.15 |
---|---|
PHP+MySQL 뉴스 관리 시스템 구현 (0) | 2022.07.14 |
PHP 파일 형식 판단 (0) | 2022.07.13 |
javamd5와 phpmd5의 불일치 문제 해결 (0) | 2022.07.13 |
도커 원클릭 Nginx+PHP 환경 구축 (자동 배치 명령 포함) (0) | 2022.07.13 |