2010-05-07 22 views
6

Tengo una aplicación que generará múltiples hilos. Sin embargo, creo que podría haber un problema con los subprocesos que acceden a los datos que no deberían ser. Soy relativamente nuevo en el roscado tan desnudo conmigo.Pasar estructuras de datos a diferentes hilos

Aquí es la estructura de la aplicación roscada (lo siento por la crudeza):

    MainThread 
       /  \ 
       /   \ 
       /   \ 
     Thread A    Thread B 
    /  \   /  \ 
    /  \   /  \ 
    /   \  /   \ 
Thread A_1  Thread A_2 Thread B_1 Thread B_2 

Bajo cada con letras hilo (que podría ser muchos), sólo habrá dos hilos y que son disparados de forma secuencial. El problema que estoy teniendo es que no estoy del todo seguro de cómo pasar una estructura de datos en estos hilos.

Entonces, la estructura de datos se crea en MainThread, se modificará en el hilo con letras (Subproceso A, etc.) específico de ese subproceso y luego se enviará una variable miembro de esa estructura de datos a Subprocesos Letter_Numbered.

Actualmente, la clase de subproceso tiene una variable miembro y cuando se construye la clase, la estructura de datos de mainthread se pasa por referencia, invocando el constructor de copia para que el subproceso tenga su propia copia para jugar.

La cadena de caracteres con número de letra simplemente toma una variable de cadena de la estructura de datos dentro del subproceso con letras. Mi pregunta es, ¿es esto aceptable? ¿Hay una forma mucho mejor de garantizar que cada hilo con letras tenga su propia estructura de datos para jugar?

Perdón por la explicación algo pobre, por favor deje los comentarios y trataré de aclarar.

EDITAR: Entonces, ¿mi constructor de hilo con letras debe tomar el VALOR de la estructura de datos, no la referencia?

+0

Quizás cuéntanos un poco sobre lo que quieres lograr. Estoy un poco desconcertado por el uso de dos hilos secuenciales: ¿te refieres a que uno comienza cuando termina el otro? – mdma

+0

+1 para la pregunta bien articulada –

+0

@mdma: ¿te refieres al lettered_numbered? Si es así, entonces sí, el hilo con letras despide el primer lettered_numbered, espera que termine (o error) y despide el segundo lettered_numbered. ¿Eso ayuda? – Robb

Respuesta

5

Haría que cada hilo creara su propia copia de la estructura de datos, p. pasas la estructura en el constructor y luego creas explícitamente una copia local. Entonces se le garantiza que los hilos tienen copias distintas. (Usted dice que es pasado por referencia, y que esto invoca el constructor de copia. Creo que quiere decir pasar de valor? Siento que es mejor hacer una copia explícitamente, no dejar dudas y aclarar su intención. De lo contrario, alguien más tarde ven y cambia tu pase por valor para pasar por referencia como una "optimización inteligente").

EDITAR: Se eliminó el comentario sobre las cadenas. Por alguna razón, estaba asumiendo .NET.

Para garantizar que las cadenas sean de propiedad privada, siga el mismo procedimiento, cree una copia de la cadena, que luego puede modificar libremente.

+0

Hmm, bien pasamos por referencia pero invoca el constructor de copia y parece asignarle a la variable miembro su propia copia. Aunque no lo he verificado por completo, podría hacer eso hoy. – Robb

+3

Las cadenas en C++ no son inmutables. – stonemetal

+0

Además, asegúrese de que sea una copia profunda para asegurarse de que todos los datos sean locales. Si puede salirse con la suya sin compartir nada entre hilos, entonces esa es la forma más segura y fácil de hacerlo. –

1

¿Has mirado boost threads?

Básicamente, se crearía una clase invocable que tiene un constructor que toma los parámetros en los que trabajará el subproceso y luego inicia el subproceso al pasar objetos de su clase invocable, inicializado y listo para funcionar.

Esto es muy similar a la forma en que Java implementa los hilos y tiene bastante sentido la mayor parte del tiempo desde el punto de vista del diseño.

+0

Por mucho que me gustaría ir a la ruta de impulso, el proyecto se encuentra actualmente en un estado en el que eso requeriría una reescritura suficiente en la que los superiores me derribarían. – Robb

+0

bien, incluso si el refuerzo no está disponible: suponiendo que se siente cómodo al iniciar subprocesos a través de un método miembro de un objeto, el patrón aún se aplica: crear una clase de subproceso que tenga: - un constructor que requiere todos los datos que thread deberá funcionar en - un método de inicio/ejecución que actúa como el punto de entrada de subproceso y el ciclo de procesamiento Para crear instancias de los objetos de subproceso y luego iniciarlos pasando el método start/run/whatever de los objetos como el punto de entrada del hilo. – sechastain

+0

Sí, esto es realmente lo que hago, excepto el uso del pase por referencia de la estructura de datos. – Robb

3

hay un patrón llamado Active Object Pattern en el que cada objeto se ejecuta en su propio hilo. Marcos como ACE apoyan esto. Si tiene acceso a dichos marcos, debe usarlos.En cualquier caso, creo que crear una nueva instancia de un objeto y permitir que exubeiga en su propio hilo es mucho más claro que invocar al constructor de copias para hacer una copia del objeto. De lo contrario, vea si puede encajar una solución que usa Thread Local Storage.

1

¿Aparentemente está haciendo una copia de los datos de cada tridente y todo funciona? entonces no hay problema.

Éstos son algunos pensamientos adicionales:

  • Si los datos es de sólo lectura, puede compartir una única estructura y todo va a estar bien, siempre y cuando cada lectura es pequeño y rápido (tipos básicos)
  • Si los datos deben escribirse, pero "privados" (o contenidos) para cada hilo, envíe una copia a cada hilo (lo que está haciendo). Advertencia: supongo que los datos no son demasiado grandes y una copia no consume demasiados recursos.
  • Si los datos deben escribirse y los nuevos valores se comparten entre hilos, entonces debe pensar en ello (leerlo) y crear un diseño adecuado. Me gusta un objeto transaccional para centralizar cada operación de lectura/escritura de hilos. Como una pequeña base de datos en la memoria. Compruebe en mutex mutex, semáforos y secciones críticas). Tratar con un gran conjunto de datos He utilizado una base de datos para centralizar las solicitudes (ver ODBM). También puede verificar las bibliotecas existentes de cola de mensajes (como MSMQ) para ordenar y sincronizar los cambios de datos.

Espero que esto ayude.

+0

Afortunadamente, la estructura de datos no será realmente compartida entre los hilos, aparte de la descrita anteriormente. Entonces, si la estructura de datos está contenida dentro de cada hilo (y cada hilo tiene su propia estructura de datos) no debería haber mucho uso para los mutex. – Robb

0

Parece poco probable que desee que cada subproceso funcione con los datos y, al menos ocasionalmente, otro subproceso reaccione a lo que otro subproceso ha hecho al trabajo de otro subproceso en los datos. Si eres verdaderamente independiente, lo que significa que ningún otro hilo realmente se preocupará por el trabajo que otro hilo ha hecho, entonces te sugiero que hagas una copia de los datos; de lo contrario, en caso de que quieras trabajar en un hilo y generar ese resultado de ese trabajo disponible para otro hilo, le sugiero que pase una referencia/puntero al objeto y luego proteja el acceso a él a través de los bloqueos para que los hilos puedan trabajar con él, sugiero un escritor individual de varias lecturas. implementación de bloqueo

Cuestiones relacionadas