De ti descripción, parece que estás escribiendo a ThreadParameter (o alguna otra estructura de datos) ANTES de iniciar cualquier subproceso secundario, y nunca volverá a escribir en ThreadParameter ... existe para que se lea según sea necesario, pero nunca se vuelva a cambiar después de su inicialización; ¿Es eso correcto? Si es así, no hay necesidad de emplear ninguna llamada de sistema de sincronización de subprocesos (o primitivas de procesador/compilador) cada vez que un subproceso secundario desea leer los datos, o incluso la primera vez para ese asunto.
El tratamiento de volátiles es un tanto específico del compilador; Sé que al menos con Diab para PowerPC, hay una opción del compilador con respecto al tratamiento de la volatilidad: utilice la instrucción PowerPC EIEIO (o MBAR) después de cada lectura/escritura en una variable, o no lo use ... esto además de prohibir las optimizaciones del compilador asociadas con la variable. (EIEIO/MBAR es la instrucción de PowerPC para prohibir el reordenamiento de E/S por parte del procesador, es decir, todas las E/S anteriores a la instrucción deben completarse antes de cualquier E/S después de la instrucción).
Desde el punto de vista de la corrección/seguridad, no está de más declararlo como volátil. Pero desde un punto de vista pragmático, si inicias ThreadParameter lo suficientemente lejos antes de StartThread(), declararlo volátil realmente no debería ser necesario (y no hacerlo aceleraría todos los accesos posteriores). Casi cualquier llamada de función sustancial (digamos, tal vez a printf() o cout, o cualquier llamada al sistema, etc.) emitiría órdenes de magnitud más instrucciones de las necesarias para garantizar que no haya forma de que el procesador no haya manejado la escritura hace mucho tiempo. ThreadParameter antes de su llamada a StartThread(). Siendo realistas, StartThread() con seguridad ejecutará instrucciones suficientes antes de que el hilo en cuestión realmente comience. Así que estoy sugiriendo que realmente no necesita declararlo volátil, probablemente ni siquiera si lo inicializa inmediatamente antes de llamar a StartThread().
Ahora en cuanto a su pregunta sobre qué pasaría si la página que contiene esa variable ya estuviera cargada en la caché de ambos procesadores antes de que el procesador ejecute la inicialización inicial: Si está utilizando una plataforma de propósito general comúnmente disponible con CPU de tipo similar, el hardware ya debería estar en su lugar para manejar la coherencia de caché para usted. El lugar en el que tiene problemas con la coherencia del caché en plataformas de uso general, ya sea multiprocesador o no, es cuando el procesador tiene cachés de datos de instrucciones separadas & y escribe código de auto modificación: las instrucciones escritas en la memoria no se pueden distinguir de los datos por lo que la CPU no invalida esas ubicaciones en la caché de instrucciones, por lo que puede haber instrucciones obsoletas en la caché de instrucciones a menos que posteriormente invalide esas ubicaciones en la caché de instrucciones (ya sea emitiendo sus propias instrucciones de ensamblaje específicas del procesador, que puede que no sea permitido hacer dependiendo de su sistema operativo y el nivel de privilegios de su subproceso, o bien emitir la llamada del sistema invalidación de caché correspondiente para su sistema operativo). Pero lo que estás describiendo no es un código de modificación automática, por lo que deberías estar a salvo en ese sentido.
Su pregunta 1 pregunta cómo hacer esto seguro en TODAS las arquitecturas de procesador. Bueno, como mencioné anteriormente, deberías estar seguro si estás usando procesadores de tipo similar cuyos buses de datos están puenteados adecuadamente. Los procesadores de propósito general diseñados para la interconexión de multiprocesadores tienen protocolos de bus snoop para detectar escrituras en la memoria compartida ... siempre y cuando la biblioteca de threading configure correctamente la región de memoria compartida. Si está trabajando en un sistema integrado, puede que tenga que configurarlo usted mismo en su BSP ... para PowerPC, necesita mirar los bits de WIMG en su configuración de MMU/BAT; No estoy familiarizado con otras arquitecturas para darte consejos sobre eso. PERO .... Si su sistema es casero o si sus procesadores no son del mismo tipo, es posible que no pueda contar con que los dos procesadores puedan husmear las escrituras de los demás; Consulte con su equipo de hardware para obtener consejos.
SomeFunction va a llamar a varios WorkerThreads, supongo. Creo que su pregunta es más como: "¿Las lecturas simultáneas me causarán un problema?" ....? – Alex
Bueno, cuando se utilizan los hilos POSIX se trabaja alrededor del enigma de la inicialización de variable global usando ['pthread_once()'] (http://linux.die.net/man/3/pthread_once) - No estoy seguro de cómo se traduce esto a su definición de "portátil". –
Imagino que la mejor solución sería 'boost: shared_mutex' y copiando el read-only en cada thread. – Pubby