如何用代碼直觀的展現(xiàn)出來????
偽代碼如下:
<?php
$main_socket = stream_socket_server("tcp://0.0.0.0:8888", $error_code, $error_msg) or die('create server failed');
while(1)
{
set_error_handler(function(){});
$new_socket = stream_socket_accept($main_socket, 5, $remote_address);
restore_error_handler();
if(!$new_socket) continue;
//屏蔽或開啟本行代碼進行調(diào)試
//stream_set_blocking($new_socket, 0);
if(pcntl_fork() == 0)
{
while(1)
{
$pid = posix_getpid();
$request = fread($new_socket, 8192);
var_dump($request);
$msg = trim($request);
if(!empty($msg))
{
$response = "{$pid} | {$remote_address} | {$msg}" . PHP_EOL;
fwrite($new_socket, $response);
}
}
exit(0);
}
}?
區(qū)別就在于:?
1、當 socket處于阻塞模式時,比如:fread系統(tǒng)調(diào)用必須等待socket有數(shù)據(jù)返回,即進程因系統(tǒng)調(diào)用阻塞;相反若處于非阻塞模式,內(nèi)核不管socket數(shù)據(jù)有沒有準備好,都會立即返回給進程。
2、另外進程阻塞和socket阻塞不是一個概念,進程阻塞是因為系統(tǒng)調(diào)用所致,socket是否阻塞只是說明socket上事件是不是可以內(nèi)核即刻處理。
我原來用IO select一直模擬不出來,我stream_socket_server創(chuàng)建了一個main資源,然后我用stream_select監(jiān)聽,然后我發(fā)起一個tcp請求,請求創(chuàng)建的時候為main的read發(fā)生改變,然后我在tcp寫字符串,這樣才在tcp_new_connection的read發(fā)生操作,所以說IO select就是非阻塞的么???如果是的話,為啥還要設(shè)置資源為非阻塞啊????因為資源發(fā)生讀操作的時候才調(diào)read
1、select是系統(tǒng)調(diào)用,必然會阻塞進程的,和socket是否阻塞并沒有關(guān)系,我第2點備注了呢。
2、這里的IO就是針對socket的網(wǎng)絡(luò)IO,是否是阻塞的,正是你題示所問的問題。
3、socket之所以設(shè)置成非阻塞,是為了同一個進程里可以更多的處理更多的tcp連接,這正是 select、poll 或者 epoll等多路復用模型能夠處理高并發(fā)的原因所在。
大佬,我stream_socket_server創(chuàng)建了一個main資源,然后我設(shè)置這個main為阻塞狀態(tài),新接受的新請求資源也設(shè)置了阻塞,一個進程還是能同時接受兩個tcp資源
1、select 模型原本就是為解決傳統(tǒng)阻塞模型中單進程只能阻塞處理一個tcp連接的問題,自然是單進程內(nèi)可以接受多個連接呢。
2、select 模型無論是main資源還是accept后的資源,這些socket句柄設(shè)置成非阻塞的目的主要在于:避免同一個進程在輪詢處理多個tcp連接IO時進程阻塞的問題,進程內(nèi)阻塞會影響后續(xù)IO的處理。