2011-09-27 16 views
5

Estoy escribiendo el código en C++. ¿Puedo encontrarme en cualquier tipo de condiciones de carrera o seg-faults?¿Pueden varios subprocesos escribir en un archivo simultáneamente, si todos los subprocesos están escribiendo en diferentes ubicaciones?

+2

Si necesita acceso simultáneo a un archivo no secuencial, le recomendaría usar un archivo mapeado en memoria. Luego, simplemente trátelo como la memoria normal y realice su propio bloqueo (que no es necesario si puede garantizar que las ubicaciones de escritura/lectura no se superpongan). –

Respuesta

6

No hay problema para hacerlo desde el punto de vista del sistema subyacente (para todos los sistemas que conozco). Sin embargo, normalmente necesitaría tener descriptores/manejadores de archivos completamente separados. Esto se debe a que el descriptor de archivo mantiene el estado, p. la posición actual del archivo

También debe comprobar la seguridad de subprocesos de la interfaz particular de C++ en el sistema de archivos que está utilizando. Esto es necesario además de la seguridad de subprocesos del sistema de archivos subyacente.

También debe considerar la posibilidad de que las E/S con rosca sean más lentas. El sistema puede tener que serializar el acceso al bus. Puede obtener un mejor rendimiento de E/S superpuestas o una secuencia de E/S dedicada alimentada a través de una canalización de productor/consumidor.

+0

En cada uno de los hilos, estoy abriendo el mismo archivo y luego escribiendo en el archivo de acuerdo con la posición que es diferente para cada hilo. Entonces, ¿puedo seguir adelante e implementar correctamente? – Invictus

+0

No podría decirlo con certeza. No has mostrado tu código. Pero mientras tengas diferentes mangos, deberías estar bien. –

1

Claro que puedes. La condición de carrera puede ocurrir dependiendo de cómo está escribiendo el código real (es decir, usando ese archivo). Además, si IO está almacenado en búfer, pueden aparecer cosas extrañas si las regiones almacenadas se superponen.

2

Depende. Los archivos no son sus identificadores y las transmisiones no son archivos. Este tres concepto diferente debe ser claro.

Ahora, el sistema operativo puede abrir el archivo varias veces devolviendo diferentes identificadores, cada uno de los cuales tiene su propio "puntero de posición". Si el archivo se abre en "modo compartir" tanto para leer como para escribir, puede buscar los controles donde desee y leer/escribir a su gusto. El hecho de que no sobrescriba depende de usted. El sistema otorga la secuencia de las operaciones para todo el archivo o parte de él (pero se requiere más información sobre el sistema operativo)

Si cada identificador está conectado a un flujo diferente, cada flujo escribirá independientemente del otro. Pero -en este caso- existe la complicación del "almacenamiento en búfer" (la escritura se puede retrasar y la lectura puede anticiparse; y puede ser más larga que la que se solicita: asegúrese de administrar la superposición adecuada enjuagando según corresponda)

+0

En cada uno de los hilos, estoy abriendo el mismo archivo y luego escribiendo en el archivo de acuerdo con la posición que es diferente para cada hilo. Entonces, ¿puedo seguir adelante e implementar correctamente? – Invictus

+0

@Invictus: debe abrir el archivo para compartir. Todo lo demás debería funcionar. –

4

Otra solución, dependiendo del tamaño del archivo y del sistema en el que se está ejecutando, es usar memory mapped files, es decir. mapeo del archivo en la memoria virtual. Esto le daría acceso directo al archivo como si fuera una pieza de memoria. De esta forma, cualquier número de hilos simplemente puede escribir en la región de la memoria y las llamadas subsiguientes para enjuagar la asignación al disco (dependiendo de la configuración de la asignación de memoria) simplemente almacenará los datos en el disco.

Tenga en cuenta que debido a las restricciones de direcciones en las plataformas de 32 bits, no será posible mapear ningún archivo más grande que generalmente 2-3 GB, dependiendo de la arquitectura y el número real de bits disponibles para hacer virtual dirección de la memoria La mayoría de los sistemas de 64 bits tienen 48 bits o más disponibles para esta tarea, lo que te permite mapear al menos 256 TB, lo cual yo diría que es más que suficiente.

+0

Tengo un sistema operativo freebsd, entonces, ¿crees que puedo usar el mapeo de memoria? – Invictus

+0

Sí. Prácticamente todos los UNIX modernos admiten mapeo de memoria a través de la función 'mmap'. La página _man_ brinda muchos más detalles al respecto, que en su caso sería [como este] (http://nixdoc.net/man-pages/FreeBSD/mmap.2.html). Generalmente, los pasos necesarios son simplemente abrir un descriptor de archivo, preasignar el tamaño de la misma si es necesario (manualmente o a través de fallocate o posix_fallocate) y luego asignarlo a la memoria y listo. –

+0

Pero, el problema aquí es que estoy usando una tabla hash para almacenar los datos entrantes y, quiero escribir esto en el archivo de salida ... Entonces, ¿hay alguna manera? – Invictus

Cuestiones relacionadas