2008-10-21 12 views
13

Tengo una aplicación C++ de subprocesos múltiples que hace una representación 3D con la biblioteca OpenSceneGraph. Estoy planeando iniciar el ciclo de renderización de OSG como un hilo separado usando boost :: hilos, pasando una estructura de datos que contiene un estado compartido al hilo. Estoy tratando de evitar cualquier cosa demasiado pesada (como mutexes) para la sincronización, ya que el bucle de renderizado debe ser bastante ajustado, y el mismo OSG intenta evitar tener que bloquear alguna vez. La mayor parte del estado compartido se establece antes de que se inicie el hilo, y nunca se cambia. Tengo algunos datos que necesitan ser cambiados, y estoy planificando un doble buffer. Sin embargo, tengo un booleano simple para señalar el hilo para suspender la representación, y luego reanudar el procesamiento, y otro para matarlo. En ambos casos, el hilo de la aplicación establece el bool, y el hilo de renderizado solo lo lee. ¿Necesito sincronizar el acceso a estos bools? Por lo que puedo decir, lo peor que puede pasar es que el bucle de render continúa para un marco adicional antes de suspender o cerrar.En una aplicación C++ de subprocesos múltiples, ¿necesito un mutex para proteger un booleano simple?

Respuesta

12

En C++ 11 y versiones posteriores, que tienen simultaneidad de estándares definidos, use std::atomic<bool> para este fin. De http://en.cppreference.com/w/cpp/atomic/atomic:

Si escribe un hilo a un objeto atómico, mientras que otro hilo lee de ella, el comportamiento está bien definido (véase el modelo de memoria para más detalles sobre las razas de datos).


La siguiente respuesta de edad puede haber sido cierto en algún momento en el pasado con algunos compiladores y algunos entornos operativos, pero no debe ser tomado como hoy:

Tienes razón, en este caso, no necesitará sincronizar los bools. Sin embargo, debe declararlos volatile, para asegurarse de que el compilador realmente los lea de memoria cada vez, en lugar de almacenar en caché la lectura anterior en un hilo (esta es una explicación simplificada, pero debería hacerlo para este propósito).

La siguiente pregunta tiene más información acerca de esto: C++ Thread, shared data

+2

Sin embargo, eso no es lo que hace 'volátil' la especificación. MSVC es un poco más indulgente con los programadores perezosos, pero sin dudas GCC optimiza, reprograma y optimiza felizmente sus accesos de memoria "volátiles". – ephemient

+0

IIRC, según la especificación, 'volátil' significa que el compilador debe asumir que la variable puede cambiar en cualquier momento fuera del control de la aplicación. Entonces, si el compilador es correcto, 'volátil' debería dar el efecto deseado. – Nick

+0

No, 'volátil' solo tiene un significado en la memoria asignada a los registros de E/S del dispositivo. Cualquier otra cosa no está especificada, y GCC no la obedece con optimizaciones más altas. – ephemient

7

¿Por qué no simplemente utilizar un interlocked variable?

+0

¿No hay gastos generales con esos? –

+0

por supuesto que hay. – shoosh

+0

Entonces es por eso que es mejor usar bool simple, es mucho más simple y rápido. –

3

Necesito Necesito un mutex en toda regla aquí - aunque el hilo de renderizado tendrá que esperar ocupado en el estado "suspendido" si no está utilizando un objeto de sincronización que admita una primitiva de espera.

Debería tener en cuenta el uso de varias primitivas de intercambio entrelazadas (InterlockedExchange en Windows). No porque las lecturas/escrituras del bool no sean atómicas, sino para garantizar que no haya comportamientos raros a los que acceda la memoria de reordenamiento del compilador en un solo subproceso.

4

En cuanto a C++ 11 y después es finalmente hilos-consciente y claramente establece que modificar un bool (u otra variable no atómica) en un hilo y acceder a él al mismo tiempo en otro es un comportamiento indefinido. En su caso, usar std::atomic<bool> debería ser suficiente para hacer que su programa sea correcto, evitando el uso de bloqueos.
No utilice volatile. No tiene nada que ver con los hilos. Para obtener más información, consulte Can I read a bool variable in a thread without mutex?

Cuestiones relacionadas