2012-04-16 15 views
12

Si se garantiza que cada hebra solo leerá/escribirá en un subconjunto específico de la matriz, ¿pueden trabajar varios hilos en la misma matriz (estática) sin recurrir a secciones críticas, etc.?¿Se puede acceder de forma segura a las matrices estáticas desde varios subprocesos?

EDIT - Esto es para el caso específico de matrices de tipos contados no de referencia y registros/registros empaquetados de los mismos.

En caso afirmativo, ¿alguna advertencia?

Mi intuición es sí, pero a veces mi instinto puede ser una fuente de información poco confiable.

+0

Bien, sé lo que eso significa ahora. Yo llamaría a ese tamaño fijo, pero ahí lo tienes. No importa si el tamaño es fijo o no. No importa si la matriz es de alcance global, local o de clase. No importa si la matriz está asignada en pila o asignada en pila. Es solo una matriz contigua de artículos. –

+0

No, mi error. Nunca había sabido ese uso. Supongo que debe haber sido introducido después de que aprendí a Delphi en el momento en que se agregaron las matrices dinámicas, ya que todas las matrices anteriores eran estáticas. En cualquier caso, estático o no hace ninguna diferencia en absoluto. –

+0

Bastante justo. Como dices, en cualquier caso, no parece haber una razón obvia de por qué el acceso concurrente debería ser un problema, pero a veces hay sutilezas oscuras que confunden tales cosas. A veces es bueno estar doblemente seguro. –

Respuesta

8

Supongamos que:

  1. tiene un único ejemplo de una matriz (estática o dinámica), y
  2. Los elementos de la matriz son los tipos de valor puros (es decir, no contienen referencias), y
  3. Cada subproceso opera en subconjuntos disjuntos y
  4. No hay nada más en el sistema que escriba en la matriz mientras los subprocesos están operando en ella.

Con estas condiciones, que creo que se cumplen con la estructura de datos y el patrón de subprocesamiento, todos los algoritmos son seguros para subprocesos.

+0

Supongo que este también sería el caso con los objetos de tipo de referencia SI se garantiza que las referencias al mismo objeto solo existen dentro de una única sub-matriz (es decir, no hay referencias comunes compartidas entre sub-arrays disjuntas). –

+2

@J ... Sí, eso es correcto. Siempre que cada hilo funcione en datos privados para ese hilo, entonces los algoritmos son seguros para subprocesos. –

+0

@DavidHeffeman, ¿Es la condición # 4 realmente necesaria? ¿Cuál es la diferencia del hilo principal u otro proceso de escritura en el conjunto de hilos que opera en él? – Arnold

7

No, esto no podría ser seguro para subprocesos, en algunas situaciones.

Veo al menos dos razones.

1. Dependerá del contenido de la matriz estática.

Si utiliza algunos tipos contados que no son de referencia (como double, integer, bytes, shortstring), no habrá ningún problema en la mayoría de los casos (al menos si los datos son leídos/solo).

Pero si utiliza algunos tipos contados de referencia (como string, interface o una matriz dinámica anidada), tendrá que encargarse de la seguridad de los hilos.

Es decir:

TMyType1: array[0..1] of integer; // thread-safe on reading 
TMyType2: array[0..1] of string; // may be confusing 

Nota adicional: si su string es, de hecho, compartida entre algunos sub-partes de la matriz estática, usted podría tener que confundir la cuenta de referencia. A menos que llame explícitamente al UniqueString() para cada uno (dentro de una sección crítica, sospecho). Para una matriz de double o integer, no tendrá este problema.

2. dependerá de la concurrencia de acceso

acceso de lectura debe hilo de seguridad, incluso para el tipo de referencia contado, pero de escritura concurrente puede ser confuso. Para un string, puede tener problemas GPF en algunos casos aleatorios, especialmente en una CPU multi-core.

Algunos aplicación segura puede ser:

  • Use secciones críticas (más pequeño posible, para reducir la sobrecarga) u otras estructuras de protección;
  • Utilice Copiar en escritura o una copia privada del contenido por hilo, para estar seguro;
  • Nota más reciente (no sobre la seguridad, pero el rendimiento): Compartir una matriz entre varias CPU puede dar lugar a sanciones de rendimiento debido a la sincronización de caché entre las CPU. El rendimiento a veces es mucho mejor cuando se utilizan matrices separadas, lo que garantiza que su ventana de almacenamiento en caché L1 no se compartirá entre las CPU.

Tenga en cuenta que estos problemas pueden ser una pesadilla para depurar, en el lado del cliente: los problemas de concurrencia de subprocesos múltiples pueden ocurrir al azar y son muy difíciles de rastrear. Cuanto más seguro, mejor, a menos que tenga problemas de rendimiento explícitos y probados.

Nota adicional: Para su caso específico de matriz estática de doble, con subparte de la matriz a la que se accede solo con un subproceso, es seguro para subprocesos. Pero no existe una regla absoluta de seguridad de subprocesos en todas las situaciones, incluso para una matriz estática. Tan pronto como utilice algunos tipos contados por referencia, o algunos punteros, puede tener problemas aleatorios.

+0

Buen punto: debería haber sido específico sobre el tipo de matriz. En este caso, los elementos son registros empaquetados de dobles (que creo que deberían ser seguros). –

+0

Esta respuesta es simplemente incorrecta en mi opinión. El objetivo de la pregunta es que cada hilo opera en sub-arrays disjuntos. Y ese único hilo que posee cada sub-matriz opera en él. Eso es seguro para hilos sin importar el tipo de elemento. –

+0

@DavidHeffernan - también es un buen punto. Las matrices de objetos contados de referencia solo apuntan a punteros, ¿sí? –

Cuestiones relacionadas