¿Por qué el código de minería de bitcoin tiene la misma declaración if dos veces?

Desde la fuente v0.9.3 miner.cpp ( https://github.com/bitcoin/bitcoin/blob/v0.9.3/src/miner.cpp#L598-L604 ):

if (GetTimeMillis() - nHPSTimerStart > 4000)
{
    static CCriticalSection cs;
    {
        LOCK(cs);
        if (GetTimeMillis() - nHPSTimerStart > 4000)
        {
        ....

¿Por qué es lo mismo si la declaración " if (GetTimeMillis() - nHPSTimerStart > 4000)" se ejecuta dos veces? GetTimeMillis() solo puede subir, por lo que parece que si la primera es verdadera, entonces la segunda declaración solo puede evaluarse como verdadera también, y es inútil. Sin embargo, asumo que esto no es del todo correcto, y también asumo que tiene algo que ver con el CCriticalSelection, pero me gustaría comprender mejor su naturaleza.

¡Gracias!

Estoy de acuerdo, creo que es un error de copiar y pegar. Tal vez deberías pedir #bitcoin-devuna doble verificación.
¿Algún otro hilo puede modificar nHPSTimerStart?
Sí, creo que sí. Podría haber bastantes hilos trabajando en la minería.
He usado algo similar antes. El primero ifcomprueba si deberíamos molestarnos en hacer el bloqueo potencialmente costoso. Si es así, entonces bloqueamos y ahora que nHPSTimerStartestá garantizado que no cambiará, podemos ejecutarlo de ifnuevo de manera segura.
Gracias, Floris, eso parece razonable. Si publicas como respuesta, podría marcarlo como tal.

Respuestas (1)

Este es el bloqueo de doble verificación , que es

...un patrón de diseño de software utilizado para reducir la sobrecarga de adquirir un bloqueo probando primero el criterio de bloqueo [...] sin adquirir realmente el bloqueo.

Este patrón puede estar plagado de problemas; incluso las personas que saben lo que están haciendo pueden verse afectadas por problemas sutiles. Véase, por ejemplo, C++ and the Perils of Double-Checked Locking de Scott Meyers y Andrei Alexandrescu.

Sin embargo, el caso de uso particular que cita parece bastante inocuo.