回答:
私は私自身の説明を書くつもりでしたが、このウィキペディアの記事はそれをかなり要約しています。
基本的な概念は次のとおりです。
コピーオンライト(「COW」と呼ばれることもあります)は、コンピュータープログラミングで使用される最適化戦略です。基本的な考え方は、複数の呼び出し元が最初は区別できないリソースを要求した場合、同じリソースへのポインタを与えることができるということです。この機能は、呼び出し元がリソースの「コピー」を変更しようとするまで維持できます。その時点で、真のプライベートコピーが作成され、変更が他の人に表示されなくなります。これはすべて、発信者に対して透過的に行われます。主な利点は、呼び出し元が変更を行わない場合、プライベートコピーを作成する必要がないことです。
また、COWの一般的な用途のアプリケーションを次に示します。
COWの概念は、Microsoft SQL Server 2005などのデータベースサーバーでのインスタントスナップショットのメンテナンスにも使用されます。インスタントスナップショットは、基になるデータが更新されたときにデータの変更前のコピーを保存することにより、データベースの静的ビューを保持します。インスタントスナップショットは、テスト用途またはモーメント依存のレポートに使用され、バックアップの置き換えには使用しないでください。
clone()
実装に使用するときにそれを使用しますfork()
-親プロセスのメモリは子のためにCOWされます。
「書き込み時にコピー」とは、多かれ少なかれそれがどのように聞こえるかを意味します。つまり、書き込みが行われるまで誰もが同じデータの単一の共有コピーを持ち、その後コピーが作成されます。通常、コピーオンライトは、同時実行性の問題を解決するために使用されます。ZFS、例えば、ディスク上のデータブロックがコピーオンライトが割り当てられます。変更がない限り、元のブロックを保持します。変更により、影響を受けるブロックのみが変更されました。つまり、新しいブロックの最小数が割り当てられます。
これらの変更は通常、トランザクションに対応するように実装されます。つまり、これらの変更にはACIDプロパティがあります。これにより、すべての更新がアトミックであることが保証されるため、いくつかの同時実行の問題が解消されます。
A
ます。プロセスは1
、2
、3
、4
それのコピーを作成し、それを読んで起動するために、各希望は、「コピーオンライト」のシステムには何もコピーされませんまだすべてはまだ読んでいますA
。プロセス3
はのコピーに変更を加えようとしていますA
。プロセス3
は実際にのコピーをA
作成し、というデータの新しいブロックを作成しますB
。プロセスは1
、2
、4
まだブロック読んでいるA
プロセスが3
今読んでいますB
。
A
、新しいコピーを作成する必要があります。まったく新しいプロセスが発生し、変更された場合にどうなるかを質問している場合、A
私の説明では、そのための十分な詳細はありません。これは実装固有のこと、あなたが仕事に実装の残りをする方法についての知識を必要とする、などのファイル\データのロック、などでしょう
私はコピーオンライトについて同じ答えを繰り返さないものとします。アンドリューの答えとチャーリーの答えはすでに非常にはっきりしていると思います。OSの例を挙げますが、この概念がどの程度広く使用されているかを説明します。
fork()
またはvfork()
を使用して、新しいプロセスを作成できます。vforkは、コピーオンライトの概念に従います。たとえば、vforkによって作成された子プロセスは、データとコードセグメントを親プロセスと共有します。これにより、分岐時間が短縮されます。execの後にvforkを実行する場合は、vforkを使用することが想定されています。したがって、vforkは、親とデータおよびコードセグメントを共有する子プロセスを作成しますが、execを呼び出すと、子プロセスのアドレス空間に新しい実行可能ファイルのイメージをロードします。
vfork
COWを使用しません。実際、子供が何かを書き込んだ場合、未定義の動作が発生し、ページがコピーされない可能性があります。実際には、逆のことがいくらか正しいと言えます。COW vfork
は、共有スペースで何かが変更されるまで機能します。
別の例を示すと、Mercurialはコピーオンライトを使用して、ローカルリポジトリのクローンを本当に「安価な」操作にします。
原則は、メモリ内のオブジェクトではなく物理ファイルについて話していることを除いて、他の例と同じです。最初は、クローンは複製ではなく、オリジナルへのハードリンクです。クローン内のファイルを変更すると、新しいバージョンを表すコピーが書き込まれます。
Ruby 'Enterprise Edition'でも、メモリを節約するための優れた方法として使用されています。
以下は、デコレータデザインパターンを使用したコピーオンライト(COW)Python実装です。不変Value
オブジェクトへの参照は、可変CowValue
オブジェクト(デコレーター)によって保持されます。CowValue
オブジェクトはすべて転送不変に要求読みValue
、オブジェクトをし、新しい不変作成することによって、すべての書き込み要求をインターセプトしValue
、正しい状態を持つオブジェクトを。CowValue
オブジェクトは、浅いが共有できるように、変数間でコピーしなければならないValue
オブジェクトを。
import abc
import copy
class BaseValue(abc.ABC):
@abc.abstractmethod
def read(self):
raise NotImplementedError
@abc.abstractmethod
def write(self, data):
raise NotImplementedError
class Value(BaseValue):
def __init__(self, data):
self.data = data
def read(self):
return self.data
def write(self, data):
pass
class CowValue(BaseValue):
def __init__(self, data):
self.value = Value(data)
def read(self):
return self.value.read()
def write(self, data):
self.value = Value(data)
v = CowValue(1)
w = copy.copy(v) # shares the immutable Value object
assert v.read() == w.read()
assert id(v.value) == id(w.value)
w.write(2) # creates a new immutable Value object with the correct state
assert v.read() != w.read()
assert id(v.value) != id(w.value)