Tengo dos hilos, uno de actualizar un int y una lectura de la misma. Este es un dato de valor donde el orden de las lecturas y escrituras es irrelevante.

Mi pregunta es, ¿tengo que sincronizar el acceso a este multi-byte valor de todos modos? O, dicho de otro modo, parte de la escritura se completa y se interrumpe, y, a continuación, la lectura de suceder.

Pensar, por ejemplo, un valor de = 0x0000FFFF que se incrementa el valor de 0 x 00010000.

Existe un tiempo donde el valor se ve como 0x0001FFFF que yo debería estar preocupado? Sin duda el más grande el tipo, el más posible que algo como esto suceda.

Siempre he sincronizado estos tipos de accesos, pero fue curioso lo que la comunidad piensa.

InformationsquelleAutor theschmitzer | 2008-09-10

15 Comentarios

  1. 47

    Al principio uno podría pensar que las lecturas y escrituras de los nativos del tamaño de la máquina son atómicas, pero hay una serie de temas a tratar, con la inclusión de coherencia de caché entre procesadores/núcleos. El uso de operaciones atómicas como la de Enclavamiento* en Windows y el equivalente en Linux. C++0x tendrá un «atómica» de la plantilla para envolver estas en una bonita interfaz multiplataforma. Por ahora, si usted está utilizando una plataforma capa de abstracción que pueden proporcionar estas funciones. ACE hace, consulte la plantilla de clase ACE_Atomic_Op.

  2. 63

    Chico, qué pregunta. La respuesta es:

    Sí, no, hmmm, bueno, depende

    Todo viene abajo a la arquitectura del sistema. En un IA32 correctamente alineado de dirección será una operación atómica. Sin alinear escribe puede ser atómica, depende del sistema de almacenamiento en caché en uso. Si la memoria se encuentra dentro de una sola caché L1 línea, entonces es atómica, de lo contrario no lo es. El ancho del bus de datos entre la CPU y la memoria RAM puede afectar a la naturaleza atómica: un alineados correctamente 16bit escribir en un 8086 era atómica, mientras que la misma escritura en un 8088 no era debido a que el 8088 sólo había un bus de 8 bits, mientras que el 8086 había un 16 bits de bus.

    También, si usted está usando C/C++ no olvides marcar el valor compartido como volátil, de lo contrario el optimizador de conversiones se piensa que la variable no se actualizan nunca en uno de tus hilos.

  3. 11

    SI usted está leyendo/escribiendo valor de 4 bytes Y es DWORD alineados en la memoria Y se está ejecutando en el I32 arquitectura, LUEGO lee y escribe son atómicas.

  4. 8

    Sí, usted necesita para sincronizar los accesos. En C++0x será una condición de carrera, y un comportamiento indefinido. Con los hilos POSIX es ya un comportamiento indefinido.

    En la práctica, podría obtener valores incorrectos si el tipo de datos es mayor que el nativo tamaño de palabra. También, otro hilo podría no ver nunca el valor escrito gracias a la optimización de mover la lectura y/o escritura.

  5. 3

    Debe sincronizar, pero en algunas arquitecturas hay formas más eficientes de hacerlo.

    Mejor es utilizar subrutinas (tal vez enmascarado detrás de macros), de modo que usted puede condicionalmente reemplazar las implementaciones con plataforma-específicos.

    El kernel de Linux ya tiene un poco de este código.

  6. 1

    A hacerse eco de lo que todo el mundo dijo arriba, el lenguaje pre-C++0x no garantiza nada acerca de la memoria compartida de acceso desde varios subprocesos. Cualquiera de las garantías de seguridad para el compilador.

  7. 0

    Estoy de acuerdo con muchos y especialmente Jason. En windows, uno es probable que el uso de InterlockedAdd y sus amigos.

  8. 0

    Lado de la caché de los temas mencionados anteriormente…

    Si el puerto el código para un procesador con un menor registro de tamaño no será atómica más.

    De la OMI, roscado problemas son demasiado espinoso riesgo.

  9. 0

    Permite tomar este ejemplo

    int x;
    x++;
    x=x+5;

    La primera instrucción se supone para ser atómicas, porque eso se traduce a una sola INC asamblea directiva que toma un único ciclo de CPU. Sin embargo, la segunda asignación requiere de varias operaciones por lo que claramente no es una operación atómica.

    Otro correo.g,

    x=5;

    De nuevo, tienes que desmontar el código para ver exactamente lo que sucede aquí.

    • Pero el compilador podría optimizar en x+=6.
  10. 0

    tc,
    Creo que el momento de utilizar una constante ( como 6) , la instrucción no se completa en un ciclo de la máquina.
    Tratar de ver el conjunto de instrucciones x+=6 como en comparación con x++

  11. 0

    Algunas personas piensan que c ++es atómica, pero tiene un ojo en la asamblea genera. Por ejemplo, con ‘gcc -S’ :

    movl    cpt.1586(%rip), %eax
    addl    $1, %eax
    movl    %eax, cpt.1586(%rip)

    El incremento de un int, el compilador de la primera carga en un registro, y los almacena de nuevo en la memoria. Esto no es atómica.

    • Este no es un problema si sólo un hilo está escrito a la variable, ya que no hay lagrimeo.

Dejar respuesta

Please enter your comment!
Please enter your name here