<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-comment">// これは記事の内容とは関係ありません PHP フロントセクション</span></span><span>
</span><span><span class="hljs-title function_ invoke__">error_reporting</span></span><span>(E_ALL);
</span><span><span class="hljs-title function_ invoke__">ini_set</span></span><span>(</span><span><span class="hljs-string">'display_errors'</span></span><span>, </span><span><span class="hljs-number">1</span></span><span>);
</span><span><span class="hljs-comment">// --------------------------------------------------</span></span><span>
</span><span><span class="hljs-meta">?></span></span><span>
</span><span><span class="hljs-comment"># マルチスレッド環境で,正しく使用する方法 socket_bind 複数のポートをバインドします?</span></span><span>
存在する PHP ソケットを使用します(socket)プログラミングネットワークの場合,`socket_bind` これは重要な機能です,ソケットを指定するためにバインドするために使用されます IP アドレスとポート。しかし,マルチスレッド環境で,直接再利用 `socket_bind` 複数のポートをバインドします可能会遇到1つ些常见问题,たとえば、ポート競合、リソースの競争とスレッドの安全性の問題。この記事では、これらの問題を正しく処理する方法を詳細に説明します。
</span><span><span class="hljs-comment">## 1つ、問題分析</span></span><span>
</span><span><span class="hljs-number">1</span></span><span>. **ポート競合**
每个端口存在する同1つ时间只能被1つ个套接字绑定。異なるスレッドが同じポートを同時にバインドしようとする場合,バインディングが失敗します。
</span><span><span class="hljs-number">2</span></span><span>. **リソース競争**
マルチスレッド環境で,複数のスレッドがオペレーティングシステムのリソースを共有します,制御されていない場合,バインディング順序は制御できない場合があります、ソケットリソースリークおよびその他の問題。
</span><span><span class="hljs-number">3</span></span><span>. **スレッドの安全性の問題**
PHP それはスレッドセーフです,但存在する使用原生 socket 拡大するとき,需要注意对同1つ资源的操作顺序,予測不可能なエラーを避けてください。
</span><span><span class="hljs-comment">## 二、正しい使用法</span></span><span>
为了マルチスレッド環境で安全地複数のポートをバインドします,次の手順を参照できます:
</span><span><span class="hljs-comment">### 1. 各スレッドはソケットを独立して作成します</span></span><span>
不要存在する多个线程间共享同1つ个套接字实例。各スレッドは独自のソケットを個別に作成する必要があります:
```php
</span><span><span class="hljs-variable">$socket</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_create</span></span><span>(AF_INET, SOCK_STREAM, SOL_TCP);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$socket</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span>) {
</span><span><span class="hljs-keyword">die</span></span><span>(</span><span><span class="hljs-string">"ソケットを作成できません: "</span></span><span> . </span><span><span class="hljs-title function_ invoke__">socket_strerror</span></span><span>(</span><span><span class="hljs-title function_ invoke__">socket_last_error</span></span><span>()));
}
</span></span>各スレッドが別のポートにバインドされていることを確認するか、ポート割り当てポリシーを使用して使用可能なポートを動的に割り当てます。
<span><span><span class="hljs-variable">$port</span></span><span> = </span><span><span class="hljs-number">8000</span></span><span> + </span><span><span class="hljs-variable">$threadId</span></span><span>; </span><span><span class="hljs-comment">// 例:各スレッドに異なるポートを割り当てます</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">socket_bind</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-string">'0.0.0.0'</span></span><span>, </span><span><span class="hljs-variable">$port</span></span><span>) === </span><span><span class="hljs-literal">false</span></span><span>) {
</span><span><span class="hljs-keyword">die</span></span><span>(</span><span><span class="hljs-string">"バインドポート <span class="hljs-subst">$port</span></span></span><span> 失敗: " . </span><span><span class="hljs-title function_ invoke__">socket_strerror</span></span><span>(</span><span><span class="hljs-title function_ invoke__">socket_last_error</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>)));
}
</span></span>ポートを割り当てたり、共有データを変更したりする場合、MutexまたはSemaphoreを使用して、人種の条件を避けることができます。たとえば、 FlockまたはPCNTL拡張機能を使用して制御します。
<span><span><span class="hljs-variable">$lockFile</span></span><span> = </span><span><span class="hljs-title function_ invoke__">fopen</span></span><span>(</span><span><span class="hljs-string">"/tmp/socket_lock_<span class="hljs-subst">$port</span></span></span><span>.lock", </span><span><span class="hljs-string">"w"</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">flock</span></span><span>(</span><span><span class="hljs-variable">$lockFile</span></span><span>, LOCK_EX)) {
</span><span><span class="hljs-comment">// 安全な操作,たとえば、ポートが利用可能かどうかを確認するか、ポートを割り当てます</span></span><span>
</span><span><span class="hljs-title function_ invoke__">flock</span></span><span>(</span><span><span class="hljs-variable">$lockFile</span></span><span>, LOCK_UN);
}
</span><span><span class="hljs-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$lockFile</span></span><span>);
</span></span>各スレッドがポートをバインドした後、 socket_listenとsocket_acceptを呼び出してクライアント接続を処理できます。
<span><span><span class="hljs-title function_ invoke__">socket_listen</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>);
</span><span><span class="hljs-keyword">while</span></span><span> (</span><span><span class="hljs-variable">$conn</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_accept</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>)) {
</span><span><span class="hljs-comment">// クライアントリクエストを処理します</span></span><span>
</span><span><span class="hljs-title function_ invoke__">socket_write</span></span><span>(</span><span><span class="hljs-variable">$conn</span></span><span>, </span><span><span class="hljs-string">"接続スレッドへようこそ <span class="hljs-subst">$threadId</span></span></span><span>\r\n");
</span><span><span class="hljs-title function_ invoke__">socket_close</span></span><span>(</span><span><span class="hljs-variable">$conn</span></span><span>);
}
</span></span>スレッドが終了したら、ソケットリソースをリリースすることを忘れないでください。
<span><span><span class="hljs-title function_ invoke__">socket_close</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>);
</span></span>socket_bindを使用して、マルチスレッド環境で複数のポートをバインドする場合、次の原則に従う必要があります。
各スレッドは、ソケットを独立して作成および結合します。
異なるスレッドが異なるポートにバインドすることを確認してください。
ミューテックスまたはセマフォを使用して、共有リソースを保護します。
リソースの漏れを避けるために、ソケットリソースを適切にリリースします。
これらの方法に従って、 socket_bindは、管理を実装し、複数のポートを同時に聴きながら、PHPマルチスレッド環境で安全かつ安定して使用できます。
<span><span><span class="hljs-comment">// 記事の終わりと PHP 論理的な無関係な部分</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"記事のコンテンツの読み込みが完了しました。\n"</span></span><span>;
</span><span><span class="hljs-meta">?></span></span><span>
</span></span>