고성능 PHP 서버 측 서비스를 구축 할 때는 종종 동시 연결을 처리하기 위해 멀티 스레드 또는 다중 프로세스 모델을 사용해야합니다. 소켓 프로그래밍은이 목표를 달성하는 데 중요한 수단입니다. 그러나 소켓 연결을 처리 할 때는 차단 및 비 블로킹 설정이 중요 해집니다. socket_set_block () 및 socket_set_nonblock () 함수는 PHP가 제공하는 기능을 사용 하여이 동작을 제어 할 수 있습니다. 그것들을 합리적으로 사용하면 I/O 차단으로 인해 스레드 또는 프로세스가 고정되어 서비스 안정성 및 응답 성을 향상시킬 수 있습니다.
이 기사에서는 멀티 스레드 또는 다중 프로세스 PHP 서비스에서 Socket_set_block () 함수를 올바르게 사용하여 문제 차단 문제를 피하고 특정 코드 예제와 함께 응용 프로그램 시나리오 및 모범 사례를 설명하는 방법을 소개합니다.
기본적으로 소켓이 차단됩니다. socket_read () 또는 socket_accept () 와 같은 함수를 블록 소켓으로 호출 할 때, 읽을 데이터가 없거나 새 연결이없는 경우, 조건이 충족 될 때까지 호출이 대기합니다.
이는 단일 스레드 모델에서는 문제가되지 않지만, 다중 스레드 또는 다중 프로세스 환경에서는 하위 스레드 또는 아동 프로세스가 막힘으로 인해 자원을 제 시간에 해제 할 수 없다면 자원 낭비로 이어지거나 프로그램이 사망 할 수 있습니다.
비 블로킹 소켓은 대기하지 않으며 즉시 반환되며 현재 데이터가 없으면 오류가 반환됩니다 (일반적으로 eagain 또는 ewouldBlock ). 오류 코드를 가져 와서 socket_last_error () 를 통해 처리 할 수 있습니다.
socket_set_block ()은 소켓을 차단 모드로 설정하는 데 사용되는 반면 역 함수 socket_set_nonblock ()은 비 블로킹 모드를 설정하는 데 사용됩니다.
멀티 스레딩 또는 멀티 프로세싱에서 권장되는 전략은 다음과 같습니다.
기본 스레드 또는 상위 프로세스에서 청취 소켓은 수락 차단을 피하기 위해 비 블로킹 모드를 채택합니다.
하위 스레드 또는 하위 프로세스에서 완전한 요청 로직의 처리를 용이하게하기 위해 단일 클라이언트 연결을 차단 모드로 전환 할 수 있습니다.
select () 및 stream_select ()를 사용하여 루프 또는 모드를 사용하면 비 블로킹 모드를 유지하는 것이 좋습니다.
다음은 다중 프로세스 모델을 기반으로하는 PHP 서비스의 예입니다.이 모델은 Socket_set_Block ()을 올바르게 사용하여 문제 차단 문제를 피하는 방법을 보여줍니다.
<code> & lt;? php set_time_limit (0); $ host = '0.0.0.0';
$ port = 9000;
// 소켓 생성
$ server = socket_create (af_inet, sock_stream, sol_tcp);
socket_bind ($ server, $ host, $ port);
socket_listen ($ server);
socket_set_nonblock ($ server); // 메인 소켓을 비 블로킹 모드로 설정합니다
echo "서버가 {$ host}에서 시작되었습니다. : {$ port} \ n";
while (true) {
$ client = @socket_accept ($ server);
if ($client === false) {
usleep(100000); // 피하다CPU게으른
continue;
}
$pid = pcntl_fork();
if ($pid == -1) {
die("Fork failed\n");
} elseif ($pid == 0) {
// 하위 프로세스
socket_close($server); // 하위 프로세스不需要监听Socket
socket_set_block($client); // 클라이언트 설정Socket차단 모드에서
$input = socket_read($client, 1024);
$output = strtoupper(trim($input));
socket_write($client, "You said: $output\n");
socket_close($client);
exit(0);
} else {
// 부모 과정
socket_close($client); // 부모 과정不处理客户端Socket
pcntl_wait($status, WNOHANG); // 피하다僵尸进程
}
}
?>
</코드>
이 예에서 기본 프로세스는 비 블로킹 소켓을 사용하여 Socket_Accept () 차단을 피하고 연결을 기다립니다. 하위 프로세스에서는 클라이언트와 다시 상호 작용하는 소켓을 블록링 모드로 전환하여 입력 및 출력의 순차적 처리를 용이하게하며 논리가 더 간단하고 신뢰할 수 있습니다.
상태 혼동을 유발할 수 있으므로 소켓을 동시에 번갈아 가도록 블록 및 비 블록을 설정하지 마십시오 . 책임을 정의하는 프로세스 또는 스레드를 관리하는 것이 더 쉽습니다.
select ()를 사용하여 여러 비 블로킹 소켓을 듣는 것은 이벤트 중심 모델에 더 효율적인 방법입니다.
PHP의 Stream_Socket_* 시리즈 기능은 일부 시나리오에서보다 친숙한 캡슐화를 제공하며 Blocking Behavi로를 제어하기 위해 Stream_set_blocking () 과 함께 사용할 수도 있습니다.
"자원이 일시적으로 사용할 수 없음"과 같은 오류 코드가 나타날 때 당황하지 마십시오. 이것은 비 블로킹 소켓의 특성 중 하나이며 논리적 재 시도 또는 이벤트 폴링을 통해 해결해야합니다.
socket_set_block () 및 socket_set_nonblock () 의 합리적인 사용은 효율적인 PHP 네트워크 서비스를 구축하는 핵심입니다. 특히 멀티 스레드 또는 다중 프로세스 환경에서 책임을 명확하게하고 적절한 차단 모드를 설정하면 스레드/프로세스 차단 문제를 피할뿐만 아니라 서비스 응답 속도 및 안정성을 향상시킬 수 있습니다.
위의 예와 전략을 통해 실제 프로젝트에서 이러한 소켓 기능을 더 잘 사용하여 강력한 PHP 배경 서비스를 만들 수 있다고 생각합니다. <code> gitbox.net </code>와 같은 개인 GIT 서비스 또는 실시간 통신 플랫폼을 구축하는 경우 정확한 소켓 제어는 필수 부분입니다.