Debo estar solo teniendo un momento, porque esto debería ser fácil, pero parece que no puedo hacerlo funcionar bien.Contador atómico en gcc
¿Cuál es la forma correcta de implementar un contador atómico en GCC?
es decir, quiero un contador que se ejecuta de cero a 4 y es seguro para subprocesos.
yo estaba haciendo esto (que se envuelve más en una clase, pero no aquí)
static volatile int _count = 0;
const int limit = 4;
int get_count(){
// Create a local copy of diskid
int save_count = __sync_fetch_and_add(&_count, 1);
if (save_count >= limit){
__sync_fetch_and_and(&_count, 0); // Set it back to zero
}
return save_count;
}
Pero se está ejecutando desde 1 a partir de 1 - 4 inclusive luego alrededor de cero.
Debería ir de 0 a 3. Normalmente haría un contador con un operador de mod pero no sé cómo hacerlo de manera segura.
Quizás esta versión sea mejor. ¿Puedes ver algún problema con él, u ofrecer una mejor solución?
int get_count(){
// Create a local copy of diskid
int save_count = _count;
if (save_count >= limit){
__sync_fetch_and_and(&_count, 0); // Set it back to zero
return 0;
}
return save_count;
}
En realidad, debo señalar que no es absolutamente crítico que cada hilo tenga un valor diferente. Si dos hilos pasaron a leer el mismo valor al mismo tiempo, eso no sería un problema. Pero no pueden exceder el límite en ningún momento.
Si __sync_fetch_and_add "realiza una operación atómica por invocación" depende de la CPU, no especificada en la pregunta. Puede ser implementado según su enfoque de comparar y cambiar, que es lo que he usado en el hardware de Sun en el pasado (bueno, la implementación de mi ex colega, muy conocida como "atomic_robin" :-)). –
No estaba hablando del número de instrucciones ejecutadas; Hay diferentes formas de implementar Exchange-add, pero todas son equivalentes siempre y cuando solo escriban en la memoria ("commit") una vez. El punto es que no se pueden construir primitivas atómicas "grandes" a partir de varias pequeñas; ellos no componen Puede usar varios pasos, pero el paso final (confirmar) debe ser una operación atómica única que hace que todo sea visible. Si hay más de un paso de este tipo al final, automáticamente tendrá una condición de carrera. –
Hola, gracias. Esto es exactamente lo que estoy buscando. No sé exactamente lo que estaba pensando con mi segunda solución. Creo que fue la falta de sueño lo que me hizo escribir un código tan bueno. – Matt