<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-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">randomGreeting</span></span><span>(</span><span><span class="hljs-params"><span class="hljs-variable">$name</span></span></span><span>) {
</span><span><span class="hljs-variable">$greetings</span></span><span> = [</span><span><span class="hljs-string">"Hello"</span></span><span>, </span><span><span class="hljs-string">"Hi"</span></span><span>, </span><span><span class="hljs-string">"Hey"</span></span><span>, </span><span><span class="hljs-string">"Greetings"</span></span><span>];
</span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-variable">$greetings</span></span><span>[</span><span><span class="hljs-title function_ invoke__">array_rand</span></span><span>(</span><span><span class="hljs-variable">$greetings</span></span><span>)] . </span><span><span class="hljs-string">", "</span></span><span> . </span><span><span class="hljs-variable">$name</span></span><span> . </span><span><span class="hljs-string">"!"</span></span><span>;
}
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">randomGreeting</span></span><span>(</span><span><span class="hljs-string">"User"</span></span><span>);
</span><span><span class="hljs-meta">?></span></span><span>
<hr>
</span><span><span class="hljs-comment"># 使用 `socket_wsaprotocol_info_import` スレッドの安全性を確保し、人種の条件を避ける方法?</span></span><span>
高い並行性ネットワークプログラミングで,特に Windows プラットフォームでネイティブを使用します Socket API 開発時,`socket_wsaprotocol_info_import` 異なるスレッドまたはプロセス間でソケット情報を共有する機能を提供します。しかし,この関数を直接使用すると、スレッドの安全性の問題と人種条件につながる可能性があります,したがって、安全を確保するためにいくつかの対策を講じる必要があります。
</span><span><span class="hljs-comment">## 1. 理解する `socket_wsaprotocol_info_import`</span></span><span>
`socket_wsaprotocol_info_import` はい Windows ソケット拡張の一部,他のスレッドまたはプロセスによって作成されたソケットをインポートできます。典型的なシナリオには含まれます:
- マルチスレッドサーバー,メインスレッドは監視を担当します,ワーカースレッドは接続を処理します。
- プロセス全体で確立されたソケットを共有します。
このモードで,同期メカニズムがない場合,複数のスレッドが同じソケットを同時に操作する場合があります,これは予測不可能な動作につながります,データが失われるか、プログラムがクラッシュした場合。
</span><span><span class="hljs-comment">## 2. 競争条件を避けるための基本原則</span></span><span>
スレッドの安全性を確保します,关键はい**1つのスレッドのみがソケットリソースに同時にアクセスします**。以下はい常用方法:
</span><span><span class="hljs-comment">### 2.1 Mutexロックを使用します(Mutex)</span></span><span>
PHP 拡張機能または基礎となるレイヤーで使用できます C/C++ Mutexロックの実装をサポートします。論理的に:
```php
</span><span><span class="hljs-variable">$mutex</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title class_">Mutex</span></span><span>(); </span><span><span class="hljs-comment">// あなたが持っていると仮定します Mutex クラスのカプセル化</span></span><span>
</span><span><span class="hljs-variable">$mutex</span></span><span>-></span><span><span class="hljs-title function_ invoke__">lock</span></span><span>();
</span><span><span class="hljs-variable">$socket</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_wsaprotocol_info_import</span></span><span>(</span><span><span class="hljs-variable">$info</span></span><span>);
</span><span><span class="hljs-comment">// 操作ソケット</span></span><span>
</span><span><span class="hljs-variable">$mutex</span></span><span>-></span><span><span class="hljs-title function_ invoke__">unlock</span></span><span>();
</span></span>
これにより、1つのスレッドのみがソケットを同時に操作できるようになります。
各ソケットには、Windowsカーネルに一意のアイデンティティがあります。ソケットが複数のスレッドによって繰り返しインポートされている場合、予測不可能な動作が発生しやすいです。ベストプラクティス:
各ソケットは一度だけインポートされます。
インポートされたソケットオブジェクトをスレッドセーフキューまたはコンテナにカプセル化します。
ソケットオブジェクトをマルチスレッド環境に保存する場合は、次のようなスレッドセーフデータ構造を使用することをお勧めします。
Mutex Lockと組み合わせたSPLのSplqueue
カスタムスレッドセーフマップ/配列
<span><span><span class="hljs-class"><span class="hljs-keyword">class</span></span></span><span> </span><span><span class="hljs-title">ThreadSafeSocketQueue</span></span><span> {
</span><span><span class="hljs-keyword">private</span></span><span> </span><span><span class="hljs-variable">$queue</span></span><span>;
</span><span><span class="hljs-keyword">private</span></span><span> </span><span><span class="hljs-variable">$mutex</span></span><span>;
</span><span><span class="hljs-keyword">public</span></span><span> </span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">__construct</span></span><span>(</span><span><span class="hljs-params"></span></span><span>) {
</span><span><span class="hljs-variable language_">$this</span></span><span>->queue = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-built_in">SplQueue</span></span><span>();
</span><span><span class="hljs-variable language_">$this</span></span><span>->mutex = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title class_">Mutex</span></span><span>();
}
</span><span><span class="hljs-keyword">public</span></span><span> </span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">push</span></span><span>(</span><span><span class="hljs-params"><span class="hljs-variable">$socket</span></span></span><span>) {
</span><span><span class="hljs-variable language_">$this</span></span><span>->mutex-></span><span><span class="hljs-title function_ invoke__">lock</span></span><span>();
</span><span><span class="hljs-variable language_">$this</span></span><span>->queue-></span><span><span class="hljs-title function_ invoke__">enqueue</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>);
</span><span><span class="hljs-variable language_">$this</span></span><span>->mutex-></span><span><span class="hljs-title function_ invoke__">unlock</span></span><span>();
}
</span><span><span class="hljs-keyword">public</span></span><span> </span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">pop</span></span><span>(</span><span><span class="hljs-params"></span></span><span>) {
</span><span><span class="hljs-variable language_">$this</span></span><span>->mutex-></span><span><span class="hljs-title function_ invoke__">lock</span></span><span>();
</span><span><span class="hljs-variable">$socket</span></span><span> = </span><span><span class="hljs-variable language_">$this</span></span><span>->queue-></span><span><span class="hljs-title function_ invoke__">isEmpty</span></span><span>() ? </span><span><span class="hljs-literal">null</span></span><span> : </span><span><span class="hljs-variable language_">$this</span></span><span>->queue-></span><span><span class="hljs-title function_ invoke__">dequeue</span></span><span>();
</span><span><span class="hljs-variable language_">$this</span></span><span>->mutex-></span><span><span class="hljs-title function_ invoke__">unlock</span></span><span>();
</span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-variable">$socket</span></span><span>;
}
}
</span></span>
複数のスレッドでソケットを操作する場合、スレッドが異常に終了すると、ソケットリソースがリリースされない場合があります。提案:
試してみるとソケットのロックを解除して閉じるようにしてください...最後に。
Register_shutdown_functionまたはスレッドを終了するコールバックを使用して、ソケットをクリーニングします。
ソケットのライフサイクルをスレッドに厳密に結合し、1つのソケットを長時間複数のスレッドに共有しないようにしてください。これにより、競争条件が発生する可能性が低下します。
socket_wsaprotocol_info_importを使用する場合、安全性の鍵は次のとおりです。
各ソケットは一度だけインポートされます。
Mutexを使用してソケット操作を保護します。
スレッドセーフデータ構造でソケットを管理します。
異常な状況でリソースリリースを確実にします。
ソケット共有の時間ウィンドウを短縮してみてください。
上記の方法により、 socket_wsaprotocol_info_importをWindowsマルチスレッドまたはマルチプロセス環境で安全に使用して、人種条件によってもたらされるリスクを回避し、プログラムの安定性と信頼性を向上させることができます。
<span></span>