[원산] Linux/Unix의 데몬 프로세스(Daemon)는 우리가 일반적으로 사용하는 httpd, mysqld 등 Windows의 서비스와 유사하게 상주 메모리에서 실행되는 프로그램이라는 것을 누구나 알고 있습니다. 일반적으로 데몬 프로세스는 C/C++로 작성되는데, 이는 포크를 통해 하위 프로세스를 생성하는 것이며, 현재 쉘 아래의 상위 프로세스가 종료되면 하위 프로세스가 터미널에 출력 정보를 생성하지 않기 위해 백그라운드에서 실행됩니다. , syslog와 같은 기능을 사용하여 로그 파일을 작성합니다.
우리는 php가 스크립팅 언어이고 php 스크립트 엔진을 통해 실행된다는 것을 알고 있으므로 데몬 프로세스를 만드는 것이 번거롭습니다. 오늘은 데몬 프로세스의 기능을 구현하기 위해 Unix/Linux 명령을 결합해 보겠습니다.
[원리] Unix에서 nohup 명령의 기능은 중단 없이 명령을 실행하는 것입니다. 동시에 nohup은 프로그램의 모든 출력을 현재 디렉터리의 nohup.out 파일에 넣습니다. 쓸 수 없으면 <사용자 홈 디렉터리> /nohup.out 파일에 저장됩니다. 따라서 이 명령을 받은 후 PHP 프로그램은 쉘 스크립트를 작성하고 루프를 사용하여 스크립트를 계속 실행합니다. 그러면 터미널 창이 닫혀 있는지 여부에 관계없이 PHP 스크립트가 계속 실행될 수 있습니다. 물론, PHP 프로세스가 종료되거나 운영 체제가 다시 시작되면 자연스럽게 종료됩니다.
[기능] 당신은 확실히 묻습니다. PHP 스크립트를 데몬으로 만드는 것이 무슨 소용이 있습니까? 물론 기본적으로 cron의 기능을 대체할 수 있는 가장 일반적인 기능도 있습니다. 예를 들어 정기적으로 수행해야 하는 특정 작업을 cron으로 수행할 수 있으며, 물론 cron이 더 이상 필요하지 않은 경우도 있습니다. 하지만 일반 Unix 서버는 재시작이 쉽지 않습니다. 게다가 텔넷을 사용할 수 있는 서버를 만드는 등 간단한 서버측 기능도 만들 수 있어요 ㅎㅎ 작은 백도어로 만들 수도 있지만 구현이 좀 복잡하네요.
[연습] 예제 1: 파일 자동 생성 이제 위의 내용을 증명하기 위해 두 가지 예제를 수행하겠습니다. 우선 첫 번째는 30초마다 자동으로 파일을 생성해 영원히 실행시키는 것이다.
먼저 운영 체제가 FreeBSD, Redhat, Fedora 또는 SUSE와 같은 Unix 또는 Linux인지 확인해야 합니다. 그런 다음 PHP 스크립트 엔진이 /usr/local/php/bin/php에 있는지 확인해야 합니다. 특정 경로는 실제 경로에 따라 작성될 수 있습니다. 스크립트 엔진이 없으면 직접 설치하십시오.
예를 들어, 현재 디렉토리가 /home/heiyeluren/이면 vi 또는 다른 편집기를 사용하여 php_daemon1.php라는 파일을 작성합니다.
$ vi php_daemon1.php
그런 다음 다음 코드를 작성합니다.
#!/usr/local/php/bin/php
<?
set_time_limit(0);
동안(1)
{
@fopen("test_".time().".txt","w");
수면(30);
}
?>
그런 다음 vi를 저장하고 종료한 다음 php_daemon1.php 파일에 실행 권한을 부여합니다.
$ chmod +x /home/heiyeluren/php_daemon1.php
그런 다음 스크립트를 백그라운드에서 실행하고 다음 명령을 실행합니다.
$ nohup /home/heiyeluren/php_daemon1.php &
위 명령을 실행하면 다음 프롬프트가 나타납니다.
[1] 82480
nohup.out에 출력 추가
차로 돌아오면 쉘 프롬프트가 나타납니다. 따라서 위 팁은 모든 명령 실행의 출력 정보가 위에서 언급한 nohup.out 파일에 저장된다는 의미입니다. 그런 다음 위 명령을 실행한 후 30초마다 현재 디렉터리에서 test_로 시작하는 더 많은 파일을 볼 수 있습니다. 예를 들어 test_1139901144.txt test_1139901154.txt 및 기타 파일은 프로그램이 백그라운드에서 실행되고 있음을 증명합니다.
그렇다면 프로그램 실행을 어떻게 종료합니까? 가장 좋은 방법은 운영 체제를 다시 시작하는 것입니다. ㅎㅎ 물론 이는 권장되지 않습니다. 프로세스를 종료하기 전에 프로세스의 PID 번호를 자연스럽게 알 수 있습니다. ID. ps 명령을 사용하여 도착을 확인할 수 있습니다.
$ps
PID TT 상태 시간 명령
82374 p3 Ss 0:00.14 -bash (bash)
82510 p3 S 0:00.06 /usr/local/php/bin/php /home/heiyeluren/php_daemon1.php
82528 p3 R+ 0:00.00 ps
위에서 우리는 PHP의 프로세스 ID가 82510임을 확인했으므로 kill 명령을 실행합니다.
$ 죽이기 -9 82510
[1]+ nohup을 죽였습니다 /home/heiyeluren/php_daemon1.php
이 프롬프트가 표시되면 프로세스가 종료되었음을 알 수 있습니다. ps를 다시 실행하면 해당 프로세스가 사라진 것을 알 수 있습니다.
$ps
PID TT 상태 시간 명령
82374 p3 Ss 0:00.17 -bash (bash)
82535 p3 R+ 0:00.00 ps
ps 명령으로 직접 프로세스를 볼 수 없는 경우 ps & apos 명령 두 개를 결합하여 보면 확실히 프로세스를 볼 수 있습니다.
위의 프로세스를 기반으로 프로세스를 확장하여 자신만의 cron 프로그램을 만들 수 있습니다. 그러면 cron이 필요하지 않습니다. 물론 이것은 단지 한 가지 방법일 뿐입니다. 이 예는 네트워크와 관련되어 있습니다. . PHP를 사용하여 대략적으로 시뮬레이션한 다음 백그라운드에서 실행하여 서버측 데몬의 효과를 얻습니다.
홈 디렉토리인 /home/heiyeluren에서 계속해서 php_daemon2.php 파일을 편집합니다.
$ vi php_daemon2.php
다음 코드를 입력하세요(코드는 PHP 매뉴얼에서 가져온 것이며 주석을 수정했습니다):
#!/usr/local/php/bin/php
<?php
/* http://www.knowsky.com/php.asp 설정에는 오류가 표시되지 않습니다*/
error_reporting(0);
/* 스크립트 시간 초과는 무한합니다*/
set_time_limit(0);
/* 고정 지우기 시작 */
ob_implicit_flush();
/* 이 머신의 IP와 열어야 할 포트 */
$주소 = '192.168.0.1';
$포트 = 10000;
/* 소켓 생성 */
if (($sock = 소켓_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0) {
echo "socket_create() 실패: 이유: " .
}
/* IP 주소와 포트 바인딩 */
if (($ret = 소켓_bind($sock, $address, $port)) < 0) {
echo “socket_bind() 실패: 이유: ” .socket_strerror($ret) .
}
/* 모니터 소켓 연결 */
if (($ret = 소켓_listen($sock, 5)) < 0) {
echo “socket_listen() 실패: 이유: ” .socket_strerror($ret) “n”;
}
/*사용자 연결을 모니터링하기 위해 무한 반복*/
하다 {
if (($msgsock = 소켓_accept($sock)) < 0) {
echo "socket_accept() 실패: 이유: " .socket_strerror($msgsock) .
부서지다;
}
/* 연결된 사용자에게 프롬프트 정보 보내기*/
$msg = “==========================================rn " .
"PHP 테스트 서버에 오신 것을 환영합니다. rnrn".
" 종료하려면 'quit'을 입력하십시오. rn" .
"서버를 종료하려면 'shutdown'을 입력하세요.rn" .
"도움말 메시지를 보려면 'help'를 입력하세요.rn" .
"=========================================rn" .
"php>";
소켓_쓰기($msgsock, $msg, strlen($msg));
하다 {
if (false === ($buf = 소켓_read($msgsock, 2048, PHP_NORMAL_READ))) {
echo “socket_read() 실패: 이유: ” .socket_strerror($ret) .
휴식 2;
}
if (!$buf = 트림($buf)) {
계속하다;
}
/*클라이언트가 quit 명령을 입력하면 클라이언트 연결을 닫습니다*/
if ($buf == '종료') {
부서지다;
}
/* 클라이언트가 shutdown 명령을 입력하면 서버와 클라이언트가 모두 종료됩니다*/
if ($buf == '종료') {
소켓_닫기($msgsock);
휴식 2;
}
/* 클라이언트가 help 명령을 입력하면 도움말 정보를 출력합니다*/
if ($buf == '도움말') {
$msg = "PHP 서버 도움말 메시지 rnrn".
" 종료하려면 'quit'을 입력하십시오. rn" .
"서버를 종료하려면 'shutdown'을 입력하세요.rn" .
"도움말 메시지를 보려면 'help'를 입력하세요.rn" .
"php>";
소켓_쓰기($msgsock, $msg, strlen($msg));
계속하다;
}
/*클라이언트 입력 명령이 없을 때 프롬프트 메시지*/
$talkback = “PHP: 알 수 없는 명령 '$buf'.rnphp> “;
Socket_write($msgsock, $talkback, strlen($talkback));
에코 "$bufn";
} 동안(참);
소켓_닫기($msgsock);
} 동안(참);
/* 소켓 연결 닫기 */
소켓_닫기($sock);
?>
위 코드를 저장하고 종료합니다.
위의 코드는 Telnet 서버측과 유사한 기능을 대략적으로 완성한 것입니다. 즉, 서버측에서 프로그램을 실행하면 클라이언트는 서버의 10000 포트에 접속하여 통신을 할 수 있습니다.
파일에 실행 권한을 추가합니다.
$ chmod +x /home/heiyeluren/php_daemon2.php
서버에서 다음 명령을 실행합니다.
$ nohup /home/heiyeluren/php_daemon2.php &
백그라운드 작업으로 들어가고 Windows 클라이언트 텔넷을 통해 이동합니다.
C:>텔넷 192.168.0.1 10000
메시지가 나타나면:
192.168.0.188에 연결 중...포트 10000에서 호스트에 대한 연결을 열 수 없습니다. 연결에 실패하면 서버가 열리지 않았거나 위 프로그램이 올바르게 실행되지 않았음을 의미합니다. PHP에 –enable이 있는지 확인하십시오. -소켓 기능. 메시지가 나타나면:
==========================================
PHP 테스트 서버에 오신 것을 환영합니다.
종료하려면 'quit'을 입력하세요.
서버를 종료하려면 'shutdown'을 입력하세요.
도움말 메시지를 보려면 'help'를 입력하세요.
==========================================
PHP>
이는 PHP로 작성된 서버 측 데몬에 성공적으로 연결되었음을 의미합니다. php> 프롬프트 후에 help, quit 및 shutdown과 같은 세 가지 명령을 실행할 수 있습니다. 이 세 가지 명령이 아닌 경우 다음 메시지가 표시됩니다.
PHP>ASDF
PHP: 알 수 없는 명령 'asdf'.
help 명령을 실행하여 도움말을 얻으세요 php> help
PHP 서버 도움말 메시지
종료하려면 'quit'을 입력하세요.
서버를 종료하려면 'shutdown'을 입력하세요.
도움말 메시지를 보려면 'help'를 입력하세요.
이 서버 측은 소개되지 않으며 사용자가 직접 확장할 수 있습니다.
프로세스 종료는 예제 1과 유사합니다.
[요약] 위의 학습을 통해 우리는 PHP를 데몬 프로세스로 사용할 수도 있다는 것을 알았습니다. 잘 설계하면 기능이 더 강력해질 것입니다. 그러나 여기서는 단지 학습 중이므로 직접 연구하고 업데이트할 수 있습니다. .
이 기사는 PHP 중국어 매뉴얼을 참조합니다. 더 많은 매뉴얼을 읽으면 매우 도움이 될 것입니다.