Pregunta

Quiero comprobar que mi interpretación es correcta. Este tipo de cosas es complicado así que estoy casi seguro de que me falta algo. Tengo un programa que consiste en un hilo en tiempo real y un hilo no en tiempo real. Quiero que el hilo no RT para ser capaz de cambiar un puntero a la memoria que se utiliza por el hilo RT.

A partir de la documentación, mi entendimiento es que esto se puede lograr en g++ con:

// global
Data *rt_data;

Data *swap_data(Data *new_data)
{
#ifdef __GNUC__
    // Atomic pointer swap.
    Data *old_d = __sync_lock_test_and_set(&rt_data, new_data);
#else
    // Non-atomic, cross your fingers.                                          
    Data *old_d = rt_data;
    rt_data = new_data;
#endif
    return old_d;
}

Este es el único lugar en el programa (que no sea la configuración inicial), donde se modifica rt_data. Cuando rt_data se utiliza en el contexto en tiempo real, se copia a un puntero local. Para old_d, más adelante, cuando es seguro que la vieja memoria no se utiliza, se liberó en el hilo no RT. ¿Es esto correcto? ¿Necesito volatile en cualquier lugar? ¿Hay otras primitivas de sincronización que debería estar llamando?

Por cierto que estoy haciendo esto en C ++, aunque estoy interesado en saber si la respuesta es diferente para C.

Gracias de antemano.

Otros consejos

Actualizar : Esta respuesta no es correcta, ya que me falta el hecho de que las garantías volatile que accede a volatile variables no son reordenados, pero no proporciona ningún tipo de garantía respecto a otra no volatile accesos y manipulaciones. Una valla de memoria proporciona estas garantías, y es necesario para esta aplicación. Mi respuesta original está por debajo, pero no actúan sobre ella. Ver esta respuesta para una buena explicación en el agujero en el entendimiento de que llevó a la siguiente respuesta incorrecta.

Respuesta original:

Sí, es necesario volatile en su declaración rt_data; volatile cualquier momento una variable puede ser modificado fuera del flujo de control de un hilo de acceder a él, debe ser declarada . Si bien es posible que pueda salir de allí sin volatile ya que está copiando a un puntero local volatile al menos ayuda con la documentación y también inhibe algunas optimizaciones del compilador que pueden causar problemas. Considere el ejemplo siguiente, adoptado de DDJ :

volatile int a;
int b;
a = 1;
b = a;

Si es posible que tenga a su valor cambió entre a=1 y b=a, a continuación, a volatile debe declararse (a menos que, por supuesto, la asignación de un valor fuera de fecha para b es aceptable). Multihilo, sobre todo a partir de primitivas atómicas, constituye una situación de este tipo. La situación también se activa con variables modificadas por manejadores de señales y por variables asignadas a posiciones de memoria impares (por ejemplo, hardware de E / S registros). Ver también esta pregunta .

De lo contrario, se ve muy bien a mí.

En C, probablemente usaría las primitivas atómicas proporcionados por GLib para esto. Que vamos a usar una operación atómica cuando estén disponibles y caen de nuevo a una aplicación correcta lenta pero basada en exclusión mutua si las operaciones atómicas no están disponibles. Boost puede proporcionar algo similar para C ++.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top