2009-03-10 28 views
76

Me gustaría saber qué es copy-on-write y para qué se utiliza? El término "matriz de copia-en-escritura" se menciona varias veces en los tutoriales de Sun JDK, pero no entendí lo que significaba.¿Qué es copy-on-write?

Respuesta

88

Iba a escribir mi propia explicación, pero this Wikipedia article prácticamente lo resume.

Aquí es el concepto básico:

Copy-on-write (a veces conocido como "vaca") es una estrategia de optimización utilizado en la programación de computadoras. La idea fundamental es que si varias personas que llaman piden recursos que son inicialmente indistinguibles, puede darles punteros al mismo recurso. Esta función se puede mantener hasta que una persona que llama intente modificar su "copia" del recurso, momento en el que se crea una copia privada verdadera para evitar que los cambios se vuelvan visibles para todos los demás. Todo esto sucede de forma transparente a las personas que llaman. La principal ventaja es que si una persona que realiza la llamada nunca realiza ninguna modificación, nunca será necesario crear una copia privada.

También aquí es una aplicación de un uso común de vaca:

El concepto VACA también se utiliza en el mantenimiento de la instantánea instantánea en servidores de bases de datos como Microsoft SQL Server 2005. Las instantáneas instantáneos preservar una vista estática de una base de datos almacenando una copia de datos previa a la modificación cuando se actualizan los datos subyacentes. Las instantáneas instantáneas se utilizan para probar usos o informes dependientes del momento y no se deben usar para reemplazar copias de seguridad.

+0

¿Para qué se utiliza? – hhafez

+0

para lo que se usa una matriz regular ... sin embargo, en algunas situaciones, este tipo de estrategia da como resultado resultados más optimizados. –

+1

@hhafez: Linux lo usa cuando usa 'clone()' para implementar 'fork()' - la memoria del proceso principal está COWed para el elemento secundario. –

39

"copiar al escribir" significa más o menos lo que parece: todo el mundo tiene una única copia compartida de los mismos datos hasta que esté escrito, y luego se hace una copia. Usualmente, copy-on-write se usa para resolver géneros de simultaneidad de problemas. En ZFS, por ejemplo, a los bloques de datos en el disco se les asigna copy-on-write; mientras no haya cambios, mantengas los bloques originales; un cambio solo cambió los bloques afectados. Esto significa que se asigna la cantidad mínima de bloques nuevos.

Estos cambios también suelen implementarse como transaccional, es decir, tienen las propiedades ACID. Esto elimina algunos problemas de concurrencia, porque entonces se garantiza que todas las actualizaciones son atómicas.

+1

Si realiza un cambio, ¿cómo se notificará a la otra su nueva copia? ¿No verían los datos incorrectos? – powder366

+7

@ powder366 - No, no verían los datos incorrectos porque cuando realizas un cambio, es cuando realmente se realiza una copia. Por ejemplo, tiene un bloque de datos llamado 'A'. Los procesos '1',' 2', '3',' 4' cada uno quiere hacer una copia y comenzar a leerlo, en un sistema de "Copiar al escribir" no se copia nada pero todo sigue leyendo 'A'. Ahora el proceso '3' quiere hacer un cambio en su copia de' A', el proceso '3' ahora hará una copia de' A' y creará un nuevo bloque de datos llamado 'B'. El proceso '1',' 2', '4' sigue leyendo el bloque' A' proceso '3' ahora está leyendo' B'. – Puddler

+0

@Puddler qué pasará si se realizan cambios en 'A'. Todos los procesos leerán la información actualizada o anterior? – Developer

6

No repetiré la misma respuesta en Copy-on-Write. Creo que Andrew's answer y Charlie's answer ya lo han dejado muy claro. Le daré un ejemplo del mundo OS, solo para mencionar cuán ampliamente se usa este concepto.

Podemos usar fork() o vfork() para crear un nuevo proceso. vfork sigue el concepto de copy-on-write. Por ejemplo, el proceso hijo creado por vfork compartirá los datos y el segmento de código con el proceso principal. Esto acelera el tiempo de horquilla. Se espera que use vfork si está ejecutando exec seguido de vfork. Entonces, vfork creará el proceso hijo que compartirá los datos y el segmento de código con su principal, pero cuando llamemos a exec, cargará la imagen de un nuevo ejecutable en el espacio de direcciones del proceso hijo.

+2

"vfork sigue el concepto de copiar con escritura". Por favor considere cambiar esta línea. 'vfork' NO usa COW. De hecho, si el niño escribe algo, puede provocar un comportamiento indefinido y no copiar páginas. De hecho, puedes decir que al revés es algo cierto. ¡COW actúa como 'vfork' hasta que algo se modifique en el espacio compartido! –

+0

Totalmente de acuerdo con Pavan. Eliminar las líneas "vfork sigue el concepto de copiar con escritura". Hoy en día, COW se usa en fork como una optimización, para que actúe como vfork y no haga una copia de los datos de los padres para el proceso secundario (si llamamos solo a exec * en el niño) –

1

También se usa en Ruby 'Enterprise Edition' como una manera ordenada de ahorrar memoria.

+2

No creo que haya querido decir " usado para "en ese sentido. – spydon

6

Solo para dar otro ejemplo, Mercurial uses copy-on-write para hacer que la clonación de repositorios locales sea una operación realmente "barata".

El principio es el mismo que en los otros ejemplos, excepto que está hablando de archivos físicos en lugar de objetos en la memoria. Inicialmente, un clon no es un duplicado sino un hard link del original. A medida que cambia los archivos en el clon, se escriben copias para representar la nueva versión.

1

He encontrado this buen artículo sobre zval en PHP, que menciona también VACA:

copiar al escribir (abreviado como ‘vaca’) es un truco diseñado para ahorrar memoria. Se usa más generalmente en ingeniería de software. Significa que PHP copiará la memoria (o asignará una nueva región de memoria) cuando escriba en un símbolo, si este ya estaba apuntando a un zval.