ホームページ  >  記事  >  php教程  >  PHP におけるいくつかの一般的なタイムアウト処理の包括的な概要

PHP におけるいくつかの一般的なタイムアウト処理の包括的な概要

WBOY
WBOYオリジナル
2016-06-13 11:57:38899ブラウズ

PHP の開発作業では、タイムアウト処理が使用されるシナリオが数多くあります。

1. 特定のバックエンド データ ソースが正常に取得されなかった場合。ページ全体の表示には影響しません
2. 1 つのページの処理パフォーマンスが低下して Web サーバーが他のページにアクセスできなくなることを防ぐために、いくつかのページ動作設定が設定されます。 🎜>3. 特定のアップロードまたは不確実な処理時間の場合、プロセス全体のすべてのタイムアウトを無制限に設定する必要があります。そうしないと、リンクの設定が不適切であると、原因不明の実行中断が発生します
4. 複数のバックエンド モジュール (MySQL、 Memcached、HTTP インターフェース) を防ぐため、単一インターフェースのパフォーマンスが低下し、フロント全体のデータ取得が遅くなり、ページを開く速度に影響を及ぼし、雪崩を引き起こします。
5. 。 。タイムアウトが必要な場面は多々あります

こういった箇所でタイムアウトの設定を考慮する必要がありますが、PHPにおけるタイムアウトはいくつかのカテゴリーに分かれており、それぞれの処理方法や方針が異なります。よく使われるものを「PHP タイムアウト処理のまとめ」にまとめました。


[Web サーバーのタイムアウト処理]
[Apache]
通常、パフォーマンスが高い場合、デフォルトのタイムアウト設定はすべて 30 秒ですが、ファイルのアップロードやネットワーク速度が非常に遅い場合、タイムアウト操作がトリガーされる可能性があります。
現在、apachefastcgiphp-fpm モードには 3 つのタイムアウト設定があります:
fastcgi タイムアウト設定:
次のように httpd.conf の fastcgi 接続構成を変更します:


コードをコピー コードは次のとおりです:


FastCgiExternalServer/home/forum/apache/apache_php/cgi-bin /php-cgi-socket/home/forum/php5/etc/php-fpm.sock
ScriptAlias/fcgi-bin/"/home/forum/apache/apache_php/cgi-bin/"
AddHandlerphp-fastcgi .php
Actionphp- fastcgi/fcgi-bin/php-cgi
AddTypeapplication/x-httpd-php.php



デフォルトカスタマイズする必要がある場合は、設定は 30 秒です。独自の設定の場合は、設定を変更する必要があります。たとえば、100 秒に変更します: (変更後、Apache を再起動します):


コードをコピーします コードは次のとおりです:


FastCgiExternalServer/home/forum/apache/apache_php/cgi-bin/ php-cgi-socket/home/forum/php5/etc/php-fpm.sock-idle -timeout100
ScriptAlias/fcgi-bin/"/home/forum/apache/apache_php/cgi-bin/"
AddHandlerphp-fastcgi.php
Actionphp-fastcgi/fcgi-bin/php-cgi
AddTypeapplication/x-httpd-php.php


タイムアウトすると、500 エラーが返され、バックエンド PHP サービスへの接続が切断され、Apache エラー ログが記録されます:
[ThuJan2718:30:152011][error][client10.81.41.110]。 ]FastCGI:commwithserver"/home/forum/apache/apache_php/cgi-bin/php-cgi"aborted:idletimeout(30sec)
[ThuJan2718:30:152011][error][client10.81.41.110]FastCGI: incompleteheaders(0bytes)receivedfromserver"/home/forum/apache/apache_php/cgi-bin/php-cgi"
その他の fastcgi 設定パラメータ 説明:

コードをコピー コードは次のとおりです。

IdleTimeout アイドル時間制限
ProcessLifeTime プロセスの最長のライフ サイクル、期限切れ その後、無条件に強制終了
MaxProcessCount プロセスの最大数
DefaultMinClassProcessCount 最小各プログラムによって開始されるプロセスの数
DefaultMaxClassProcessCount 各プログラムによって開始されるプロセスの最大数
IPCConnectTimeout プログラム応答タイムアウト
IPCCommTimeout およびプログラム通信の最大時間 上記のエラーは、この値の設定が小さすぎることが原因で発生する可能性があります。
MaxRequestsPerProcess は、各プロセスが完了できる最大プロセス数です。

[ Lighttpd ]
Configuration: lighttpd.conf
Lighttpd 設定のタイムアウトに関連するパラメータは次のとおりです (スペースを考慮して、書き込み読み取りタイムアウトのみ、書き込みタイムアウト パラメータは同じです):
主に関連するオプション:
server.max -keep-alive-idle=5
server.max-read-idle=60
server.read-timeout=0
server.max-connection-idle=360

コードをコピー コードは次のとおりです:


#各キープアライブの最大リクエスト数、デフォルト値は 16 です。
server.max-keep-alive-requests=100
#キープアライブの最大待機時間、単位は秒、デフォルト値は 5
server.max-keep-alive-idle=1200
#lighttpd の作業サブプロセスの数、デフォルト値は 0、単一プロセス操作
server.max-worker=2
#ユーザーがリクエストを送信する際の最大一時停止時間 (秒単位) を制限します。
#ユーザーがリクエストの送信プロセス中に一時停止しすぎる場合 (リクエストは無効になります)。完了)、lighttpd は積極的に切断します
#デフォルト値は 60 (秒) です
server.max-read-idle=1200
#ユーザーが応答を受信するときの最大中間停止時間 (秒単位) を制限します。 ),
#応答を受信して​​いる間 (完了していない) にユーザーが長時間停止した場合、lighttpd は積極的に切断します
# デフォルト値は 360 (秒) です
server.max -write-idle=12000
#クライアント要求の読み取りのタイムアウト制限。単位は秒で、制限がないことを示すには 0 に設定されます。
#設定が max-read-idle より小さい場合、read-timeout が有効になります。
server. read-timeout=0
#クライアントに応答ページを書き込むためのタイムアウト制限 (秒単位)。制限なしを示すには 0 に設定します
#設定が max-write-idle 未満の場合、write-timeout
server.write-timeout=0
#mod_proxy_core を使用する場合のバックエンドとの対話時間の上限です。
server.max-connection- idle=1200


注:
キープアライブ接続での連続したリクエストの場合、最初のリクエストの内容を送信する最大間隔は、2 番目のリクエストのパラメータ max-read-idle によって決まります。リクエスト以降、リクエストの内容を送信する最大間隔はパラメータ max-keep-alive-idle によって決定されます。リクエスト間のタイムアウトも max-keep-alive-idle によって決まります。リクエストコンテンツの送信の合計タイムアウトは、パラメータ read-timeout によって決まります。 Lighttpd がバックエンドと対話するためのタイムアウトは、max-connection-idle によって決まります。
詳細情報:
http://www.snooda.com/read/244
[ Nginx ]
設定: nginx.conf

コードをコピー コードは次のとおりです:


http{
#Fastcgi: (バックエンド fastcgi に有効、fastcgi はプロキシ モードに属しません)
fastcgi_connect_timeout5;#Connection timeout
fastcgi_send_timeout10; #書き込みタイムアウト
fastcgi_read_timeout10;#読み取りタイムアウト
#プロキシ: (プロキシ/アップストリームに有効)
proxy_connect_timeout15s;#接続タイムアウト
proxy_read_timeout24s;#読み取りタイムアウト
proxy_send_timeout 10代; # 書き込みタイムアウト
}


説明:
Nginx のタイムアウト設定は非常に明確で理解しやすいですが、タイムアウトによって引き起こされる多くの問題があります。 。
詳細情報:
http://hi.baidu.com/pibuchou/blog/item/a1e330dd71fb8a5995ee3753.html
http://hi.baidu.com/pibuchou/blog/item/7cbccff0a3b77dc60b46e024.html
http://hi.baidu.com/pibuchou/blog/item/10a549818f7e4c9df703a626.html
http://www.apoyl.com/?p=466
[PHP 自体のタイムアウト処理] 】
[ PHP-fpm ]
設定: php-fpm.conf

コードをコピー コードは次のとおりです:




//...
ApacheMaxClients ディレクティブと同等の数を設定します。オリジナルのphp.fcgiの環境
任意の pm_style で使用されます。
#php-cgi プロセス数
128
その後ワーカープロセスが終了するまでのタイムアウト (秒)
'max_execution_time' オプションがスクリプトの実行を停止しない場合に使用する必要がありますなぜか
「0s」は「オフ」を意味します
#php-fpm リクエストの実行タイムアウト、0s はタイムアウトしないことを意味します。それ以外の場合はタイムアウトの秒数として Ns を設定します
0s単一のリクエストを処理するためのタイムアウト (秒)
'0s' はオフを意味します'


注:
php.ini には、PHP スクリプトの最大実行時間を設定できるパラメーター max_execution_time がありますが、php-cgi (php-fpm) では、このパラメーターは有効になりません。 PHP スクリプトの最大実行を実際に制御できる場合:
0s
つまり、mod_php5.so モードを使用して max_execution_time を実行すると、有効になりますが、php の場合、-fpm モードで実行している場合は有効になりません。
詳細情報:
http://blog.s135.com/file_get_contents/
[ PHP ]
設定: php.ini
オプション:
max_execution_time=30
またはコードで設定します:
ini_set("max_execution_time",30);
set_time_limit(30);
注:
を 0 に設定すると、タイムアウトになることはありません。ただし、phpのsafe_modeがオンになっている場合、これらの設定は有効になりません。
効果は同じですが、php-fpm で request_terminate_timeout が設定されている場合、特定のコンテンツは php-fpm 部分を参照する必要があります。max_execution_time は有効になりません。
[バックエンドとインターフェースのアクセスタイムアウト]
[HTTP アクセス]
一般に、HTTP にはさまざまな方法でアクセスします。主に、curl、socket、file_get_contents() などのメソッドです。
相手のサーバーが応答しない場合、サーバー全体が簡単に停止してしまうため、http にアクセスする際のタイムアウトの問題も考慮する必要があります。
[CURL アクセス HTTP]
CURL は、HTTP プロトコル インターフェイスにアクセスするために一般的に使用される信頼性の高いライブラリ ライブラリであり、高いパフォーマンスといくつかの同時実行サポート機能を備えています。
CURL:
curl_setopt($ch,opt) は、主に以下を含むいくつかのタイムアウト設定を設定できます:
*(重要) CURLOPT_TIMEOUT は、cURL が実行できる最大秒数を設定します。
*(重要) CURLOPT_TIMEOUT_MS は、cURL が実行できる最大ミリ秒数を設定します。 (cURL7.16.2 で追加。PHP5.2.3 から利用可能。)
接続を開始するまでに CURLOPT_CONNECTTIMEOUT が待機する時間。0 に設定すると、無期限に待機します。
CURLOPT_CONNECTTIMEOUT_MS 接続試行を待機する時間 (ミリ秒単位)。 0 に設定すると、無限に待機します。 cURL7.16.2で追加されました。 PHP5.2.3から利用可能です。
CURLOPT_DNS_CACHE_TIMEOUT は、DNS 情報をメモリに保存する時間を設定します。デフォルトは 120 秒です。
curl の通常の第 2 レベルのタイムアウト:
$ch=curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt ($ch,CURLOPT_TIMEOUT,60);// 秒数を設定するだけです
curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
curl_setopt($ch,CURLOPT_USERAGENT,$define_vars['HTTP_USER_AGENT) ' ]);
curl の通常の第 2 レベルのタイムアウトを使用します:
curl_setopt($ch,CURLOPT_TIMEOUT,60);
curl がミリ秒のタイムアウトを必要とする場合は、次を追加する必要があります:
curl_easy_setopt(curl,CURLOPT_NOSIGNAL) ,1L) ;
または:
curl_setopt($ch,CURLOPT_NOSIGNAL,true); ミリ秒レベルのタイムアウト設定をサポートできます
curl のミリ秒レベルのタイムアウトの例:

コードをコピー コードは次のとおりです:

if(!isset($_GET['foo'])){
//クライアント
$ch=curl_init('http://example.com/');
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_NOSIGNAL,1); ;//ミリ秒に注意してください。タイムアウトは設定する必要があります。
curl_setopt($ch,CURLOPT_TIMEOUT_MS,200); //cURL7.16.2 で追加されたミリ秒単位のタイムアウト。 PHP5.2.3 以降で利用可能
$data=curl_exec($ch);
$curl_error=curl_error($ch); ;
if($curl_errno>0){
echo "cURLError($curl_errno):$curl_errorn";
}else{
echo "Datareceived:$datan"; >}else{
//サーバー
sleep(10);
echo "完了"
}
?>



その他のヒント:

1. エクスペリエンスの概要によると、cURL バージョン >= libcurl/7.21.0 バージョンでは、ミリ秒のタイムアウトが確実に有効になることを覚えておいてください。

2.curl_multi のミリ秒タイムアウトにも問題があります。 。単一アクセスはミリ秒レベルのタイムアウトをサポートしますが、複数の呼び出しが並行して行われる場合、curl_multi は不正確になります
[ストリーム処理を介した HTTP へのアクセス] HTTP を実行するには、curl に加えて、fsockopen またはファイル操作関数をよく使用します。したがって、この部分のタイムアウト処理も必要です。
一般的な接続タイムアウトは直接設定できますが、ストリーム読み取りタイムアウトは個別に処理する必要があります。

処理する独自のコードを作成します:



コードをコピーします
コードは次のとおりです:

$tmCurrent=gettimeofday (); $intUSGone=($tmCurrent['sec']-$tmStart['sec'])*1000000 ($tmCurrent['usec']-$tmStart[' usec']);

if($intUSGone>$this->intReadTimeoutUS){

returnfalse;
}


または、組み込みのストリーム処理関数 stream_set_timeout( ) と stream_get_meta_data() を使用して処理します:


コードをコピー

コードは次のとおりです:


//タイムアウト秒
$timeout=5;
$fp=fsockopen("example.com",80,$errno,$errstr,$timeout);
if($fp){
fwrite($fp,"GET/HTTP/1.0rn");
fwrite($fp,"Host:example.comrn"); fp,"Connection:Closernrn");
stream_set_blocking($fp,true);//重要、非ブロッキング モードに設定します
stream_set_timeout($fp,$timeout);//タイムアウトを設定します
$ info =stream_get_meta_data($fp);
while((!feof($fp))&&(!$info['timed_out'])){
$data.=fgets($fp,4096); 🎜 >$info=stream_get_meta_data($fp);
ob_flush;
flush();
if($info['timed_out']){
echo "ConnectionTimedOut!";
}else{
echo$data;
}
}


file_get_contents タイムアウト:



コードをコピー

コードは次のとおりです。 $timeout=array(

'http'=>array(
'timeout'=> 5//設定 秒単位のタイムアウト
)
)
$ctx=stream_context_create($timeout);
$text=file_get_contents("http://example.com/",0, $ ctx);
?>


fopen タイムアウト:



コードをコピーします。

コードは次のとおりです。 > $timeout=array(

'http'=>array(

'timeout'=>5//タイムアウトを秒単位で設定します
)
);
$ctx=stream_context_create($timeout);
if($fp=fopen("http://example.com/","r",false,$ctx)){
while($c=fread($fp,8192)){
echo$c;
}
?>


[MySQL]

php の mysql クライアントには、mysqli にも mysql にもタイムアウトを設定するオプションがありませんが、libmysql にはタイムアウト オプションが用意されていますが、それを非表示にします。 php 以上です。
PHP でこの操作を使用するには、いくつかの MySQL 操作定数を自分で定義する必要があります。
MYSQL_OPT_READ_TIMEOUT=11;

MYSQL_OPT_WRITE_TIMEOUT=12;オプションを使用して、対応する値を設定できます。
ただし、mysql の内部実装には注意すべき点があります。1. タイムアウト設定の単位は秒で、最小構成は 1 秒です。
2. ただし、mysql の基本的な読み取りは再試行されます。 2 回なので、実際の時間は 3 秒になります。
2 回と 1 回の再試行 = タイムアウトの 3 倍です。つまり、最小タイムアウトは 3 秒であり、この値を下回ることはありませんが、ほとんどのアプリケーションでは許容されます。少数のアプリケーション向けに最適化する必要があります。
mysql へのアクセスのタイムアウトを設定する php インスタンスを表示します:



コードをコピーします

コードは次のとおりです:


//読み取りおよび書き込みのタイムアウト定数を自分で定義します if(!define('MYSQL_OPT_READ_TIMEOUT')){ define('MYSQL_OPT_READ_TIMEOUT',11); 🎜>if(!define('MYSQL_OPT_WRITE_TIMEOUT') ')){ define('MYSQL_OPT_WRITE_TIMEOUT',12) }

//タイムアウトを設定します

$mysqli=mysqli_init(); >$mysqli->options(MYSQL_OPT_READ_TIMEOUT,3 );
$mysqli->options(MYSQL_OPT_WRITE_TIMEOUT,1)
//データベースに接続します
$mysqli->real_connect("localhost") ,"root","root","test") ;
if(mysqli_connect_errno()){
printf("Connectfailed:%s/n",mysqli_connect_error());
}
//クエリを実行 sleep1 秒 タイムアウトなし
printf("Hostinformation:%s/n",$mysqli->host_info)
if(!($res=$mysqli-) >query('selectsleep(1)'))) {
echo "query1error:".$mysqli->error."/n";
}else{
echo "Query1:querysuccess/ n";
}
//スリープのクエリを 9 秒間実行するとタイムアウトになります
if(!($res=$mysqli->query('selectsleep(9)'))){
echo "query2error:".$mysqli->error."/ n";
}else{
echo "Query2:querysuccess/n";
$mysqli->close ();
echo "closemysqlconnection/n";
?>


http://blog.csdn.net/heiyeshuwu/article/details/ 5869813

【Memcached】

[PHP 拡張機能]
php_memcache クライアント:
接続タイムアウト: boolMemcache::connect(string$host[,int$port[,int$timeout ]])
明示的なタイムアウト設定パラメーターの取得または設定中に何も起こりません。
libmemcached クライアント: PHP インターフェイスには明らかなタイムアウト パラメーターがありません。
注意: したがって、PHP で Memcached にアクセスする場合は、いくつかの操作を自分でハックするか、オンライン パッチを参照する必要があるため、多くの問題が発生します。
[C&C アクセス Memcached]
クライアント: libmemcached client

注: memcache のタイムアウト設定は、5 ミリ秒や 10 ミリ秒など、より小さく設定できます。この時間を超える場合は、クエリを実行することをお勧めします。データベース。
以下は、セットデータの接続と読み取りのタイムアウトの C の例です:


コードをコピー

コードは次のとおりです:


//接続タイムアウトの作成 (Memcached への接続)
memcached_st*MemCacheProxy::_create_handle()
{
memcached_st*mmc=NULL;
if( _mpool!=NULL){//getfrompool
mmc=memcached_pool_pop(_mpool,false,&prc);
if(mmc==NULL){
__LOG_WARNING__("MemCacheProxy","gethandlefrompoolerror[%d]") ,(int)prc);
returnmmc;
}
memcached_st*handle=memcached_create(NULL);
__LOG_WARNING__(" ","create_handleerror");
returnNULL;
}
//接続/読み取りタイムアウトを設定します
memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_HASH,MEMCACHED_HASH_DEFAULT);
memcached_behavior_set(handle,MEMCACHED_BEHAVI) OR_NO_B ロック、_noblock) ;//タイムアウト設定を有効にするために、パラメータ MEMCACHED_BEHAVIOR_NO_BLOCK が 1 に設定されています。タイムアウトが設定されていない場合、タイムアウトは有効になりません。重要なときに雪崩が発生しやすくなります。
memcached_behavior_set(handle) ,MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT,_connect_timeout);//接続タイムアウト
memcached_behavior_set(handle ,MEMCACHED_BEHAVIOR_RCV_TIMEOUT,_read_timeout);//読み取りタイムアウト
memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_SND _TIMEOUT, _send_timeout);//書き込みタイムアウト
memcached_behavior_set(handle, MEMCACHED_BEHAVIOR_POLL_TIMEOUT,_poll_timeout );
//一貫したハッシュを設定します
/ /memcached_behavior_set_distribution(handle,MEMCACHED_DISTRIBUTION_CONSISTENT);
memcached_behavior_set(handle,MEMCACHED_BEHAVIOR_DISTRIBUTION,MEMC) ACHED_DISTRIBUTION_CONSISTENT);
memcached_returnrc;
for(uinti=0) ;i<_server_count>rc=memcached_server_add(handle, _ips[i],_ports[i]);
if(MEMCACHED_SUCCESS!=rc){
__LOG_WARNING__("MemCacheProxy"," addserver[%s:%d] が失敗しました。",_ips[i],_ports [i]);
}
}
_mpool=memcached_pool_create(handle,_min_connect,_max_connect);
if( _mpool==NULL){
__LOG_WARNING__("MemCacheProxy","create_poolerror" );
returnNULL;
mmc=memcached_pool_pop(_mpool,false,&prc); =NULL){
__LOG_WARNING__("MyMemCacheProxy","gethandlefrompoolerror[%d ]",(int)prc);
}
//__LOG_DEBUG__("MemCacheProxy","gethandle[%p]", handle);
returnmmc;
}
//設定 キーがタイムアウトする (データを memcached に設定する)
boolMemCacheProxy::_add(memcached_st*handle, unsignedint*key, constchar*value,intlen) 、unsignedinttimeout)
{
memcached_returnrc;
chartmp[1024] ;
snprintf(tmp,sizeof(tmp),"%u#%u",key[0],key[1]) ;
//タイムアウト値があります
rc=memcached_set(handle, tmp,strlen(tmp),(char*)value,len,timeout,0);
if(MEMCACHED_SUCCESS!=rc) {
returnfalse;
}
returntrue;
}


//Memcache 読み取りデータ タイムアウト (未設定)
libmemcahed ソース コードのインターフェイス定義:
LIBMEMCACHED_APIchar*memcached_get(memcached_st*ptr,constchar*key,size_tkey_length,size_t*value_length,uint32_t *flags,memcached_return_t*error);
LIBMEMCACHED_APImemcached_return_tmemcached_mget(memcached_st*ptr,constchar*const*keys,const)サイズ_t*キーの長さ、サイズ_tキーの数);

インターフェースを見ると、データを読み取るときにタイムアウト設定がないことがわかります。
詳細情報:
http://hi.baidu.com/chinauser/item/b30af90b23335dde73e67608
http://libmemcached.org/libMemcached.html

[タイムアウトの実装方法]

プログラムにはタイムアウト機能が必要です。たとえば、バックエンドの Socket モジュールに単独でアクセスし、その Socket モジュールが上記のいずれにも属していない場合、そのプロトコルもプライベートです。したがって、現時点でいくつかのタイムアウト処理戦略を実装するには、いくつかの処理コードが必要になる可能性があります。
[PHP でのタイムアウトの実装]
1. 初級: 最も単純なタイムアウトの実装 (第 2 レベルのタイムアウト) アイデアは非常に単純です。バックエンドに接続し、それをノンブロッキング モードに設定します。接続がない場合は、ループを続けて、現在時刻とタイムアウト時刻の差を確認します。
元のタイムアウトは phpsocket に実装されています: (ループごとに現在の時間が差し引かれ、パフォーマンスが低下し、CPU 使用率が高くなります)



コードをコピー

コードは次のとおりです:

<$host="127.0.0.1"; $port="80"; =15;//timeoutin秒

$socket=socket_create(AF_INET,SOCK_STREAM,SOL_TCP)

ordie("Unabletocreatesocketn")
socket_set_nonblock($socket) //必ずブロッキング モードに設定してください
ordie("Unabletosetnonblockonsocketn");
$time=time();
//ループするたびに対応する値を減算します
while(!@socket_connect($socket,$host,$port) )//接続がない場合は無限ループが続きます
{
$err=socket_last_error($socket)
if($err==115||$err==114)
{
if((time()- $time)>=$timeout)// タイムアウトしたかどうかを確認する必要があるたびに
{
socket_close($socket)
die("Connectiontimedout.n");
sleep(1);
}
die(socket_strerror($err)."n");
socket_set_block($this->socket)/ / ブロックモードを復元
ordie("Unabletosetblockonsocketn")

;
2. アップグレード: PHP 独自の非同期 IO を使用して実装します (ミリ秒タイムアウト)
説明:
非同期 IO: 非同期 IO の概念は同期 IO の反対です。非同期プロシージャ呼び出しが発行された場合、呼び出し元は結果をすぐには取得しません。実際に通話を処理するコンポーネントは、通話が完了するとステータス、通知、コールバックを通じて発信者に通知します。非同期 IO は、ビットを小さなグループ (8 ビット、1 文字、またはそれ以上) に転送します。送信者はいつでもこれらのビットのグループを送信できますが、受信者はそれらがいつ到着するかわかりません。
多重化: 多重化モデルは複数の IO 操作を検出し、操作できるように操作可能なコレクションを返します。これにより、ブロッキング IO が各 IO をいつでも処理できないという判断と、システム リソースの非ブロッキング占有が回避されます。
socket_select() を使用してタイムアウトを実装します。
socket_select(...,floor($timeout),ceil($timeout*1000000));
select の機能: タイムアウトをマイクロ秒レベルに設定できます。 !
socket_select() のタイムアウト コードを使用します (理解するには、非同期 IO プログラミングの知識が必要です)

コードをコピーします コードは次のとおりです


プログラミング呼び出しクラスプログラミング#
$server=newServer;
for(;;){ <🎜; >foreach($select->gt ;can_read(0)as$socket){
if($socket==$client->socket){
//NewClientSocket
$select->add( socket_accept($client->socket));
}
else{
//$socket に何かあります
}
}
? >非同期多重化IOとタイムアウト接続処理クラスのプログラミング
classselect{
var$sockets;
functionselect($sockets){
$this->sockets=array ();
foreach($socketsas$socket){
$this->add($socket);
}
}
functionadd($add_socket){
array_push( $this-> ;sockets,$add_socket);
}
functionremove($remove_socket){
$sockets=array()
foreach($this->socketsas$socket); 🎜>if( $remove_socket!=$socket)
$sockets[]=$socket;
}
$this->sockets=$socket;
functioncan_read($timeout; ){
$read=$this->sockets;
socket_select($read,$write=NULL,$excel=NULL,$timeout);
return$read
; >functioncan_write($ timeout){
$write=$this->sockets;
socket_select($read=NULL,$excel,$timeout);
return$write; 🎜>}
}
?>



[C&C でのタイムアウト実装]

通常、LinuxC/C では、alarm() を使用できます。タイマー メソッドを設定して第 2 レベルのタイムアウトを実現するか、select()、poll()、epoll() などの非同期多重 IO を使用してミリ秒レベルのタイムアウトを実現します。これを実現するために、セカンダリのカプセル化された非同期 IO ライブラリ (libevent、libev) を使用することもできます。
1. アラーム内のシグナルを使用してタイムアウト (第 2 レベルのタイムアウト) を実装します。
説明: Linux カーネルの接続タイムアウトは、通常 75 秒です。接続から早く戻るために、10 秒などの短い時間を設定できます。ここでは、信号処理メカニズムを使用し、アラームを呼び出し、タイムアウト後に SIGALRM 信号を生成します (select を使用して実装することもできます)
接続設定タイムアウトのコード例を実装するには、alarym 秒を使用します:



コードをコピー

コードは次のとおりです:


//信号処理関数

staticvoidconnect_alarm(intsigno) { debug_printf("SignalHandler") ; return; }

//アラームタイムアウト接続実装

staticvoidconn_alarm()
{
Sigfunc*sigfunc;//既存の信号処理関数
sigfunc=signal(SIGALRM) ,connect_alarm);// 信号処理関数 connect_alarm を作成し、(存在する場合) 既存の信号処理関数を保存します
inttimeout=5
// 目覚まし時計を設定します
if(alarm(timeout)!= 0){
// ...目覚まし時計が設定され、処理されました
}
//接続操作を実行します
if(connect(m_Socket,(structsockaddr*)&addr,sizeof(addr) )<0){
if(errno ==EINTR){// エラー番号が EINTR に設定されている場合は、タイムアウトが中断されたことを意味します。
debug_printf("Timeout"); >

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。