テクノロジーの限界に到達したい場合、学習プロセスは何が起こっているのか、そしてなぜ起こっているのかを知ることにあります。
今日は、PHP の基礎となるコピーオンライト (スプリットオンライトとも呼ばれます) について説明します。
まず、コードの一部を見てみましょう:
2 つのコードの出力結果は誰もが知っていると思いますが、今日は何が起こったのかについて話します。
下の図はPHPの記憶変数の構造です(説明の便宜上コメントを書いています)、zend.hはZendディレクトリにあります。
構造体には、変数値、その構造体を指す変数の数、変数タイプ、参照変数かどうかなどに関する情報が保存されていることがわかります。
では、最初の印刷物はどうなるでしょうか?変数情報は構造体に入り、相関関係は次のようになります:
$name = '8:30 in the Even';
$myName = $name; このとき、$name と $myName は、
$myName = $name; は、このプロセス中に積極的に 2 つの構造体に変換されないことがわかりました (これは、1 つの構造体のみを使用してメモリを節約する、PHP 内の一種の最適化とも考えられます)。
それでは、コードが $myName = ‘gzchen’; まで実行されると、構造はどのように変化するのでしょうか?最初の出力では2つの変数で構造が共有されているので、このときどちらかの変数を変更すると2つの値も一緒に変化するのでしょうか?純粋に構造の論理から言えば、結局のところ、この構造は誰もが共有しているのです。
次に、2 番目の印刷がどのようになるかを見てみましょう。関連する変更は次のとおりです。
は、$name と $myName を同時に 'gzchen' に変更しませんでしたが、一方をコピーしました。 more 2つの構造体が出てきて、その2つの構造体がそれぞれ$nameと$myNameに対応します。
これは問題を引き起こすコピーオンライト (COW) であり、 $myName = $name; が割り当てられたときに 2 つの構造に分割されず、変数の 1 つを書き換えたときに有効になります。レプリケーション(低速分割とも呼ばれます)。
疑似コードは次のとおりです:
別のコードを見てみましょう:
出力は「b」ですが、途中で何が起こったでしょうか?
実際、foreach 走査プロセス中、$arr (元の配列) は直接操作されませんが、$arr は $arrcopy にコピーされます (実際にはコピーです。ここでは代わりに $arrcopy を使用します)。実際、操作は常に $arrcopy です。一般的なプロセスは次のとおりです。
は、最初 ($arr = $arrcopy) でまだ共有していることがわかります。同じ構造ですが、$arr[$k] = $v が再度割り当てられると、コピーオンライトが発生し、構造が分割されます。
そして、前に述べたように、foreach は $arrcopy 上で動作するため、$arr の構造体ポインターは最初の位置に留まります (構造が異なるため、$arrcopy は $arr に同期的に値を割り当てることができません)。
実際、この種のテクノロジーは通常、インタビューでのみ使用されます。結局のところ、この書き方を日常の開発で使用する人はほんのわずかであり、当面はそれを理解していない友人もお金を払いません。 「書き込み中にコピー」という状況があることを知っている限り、それだけです。
上記は PHP の基礎的な分析を紹介しています。 Cow と php を含む、書き込み時の Cow のコピーについては、PHP チュートリアルに興味のある友人に役立つことを願っています。