Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

276
Vistas
El problema de carreras de datos no se puede reproducir con este fragmento de código

Tengo el siguiente fragmento de código que quiero usar para mostrar el caso de las carreras de datos en la programación de subprocesos múltiples en C. Y lo compilé y lo ejecuté con gcc test.c -O0 -lpthread -o test && ./test en un sistema Linux x86 (con un solo núcleo), cerca de cien veces, pero no vi ningún caso que el valor impreso es incorrecto (200000). ¿Significa que el x86 o el compilador podrían garantizar que cada modificación en una variable int sea segura para subprocesos? O algo malo con mi programa?

Editar : entonces, como @Sinic y yo probamos, la pregunta se actualizaría a: ¿Por qué las carreras de datos rara vez ocurren en una CPU de un solo núcleo? ¿O no habrá problemas de carreras de datos en una CPU de un solo núcleo? Porque, AFAIK, los subprocesos se programarían aleatoriamente incluso en una CPU de un solo núcleo. Entonces, el resultado sería un desastre también.

 // test.c #include <threads.h> #include <stdio.h> #define THREAD_COUNT 20 #define THREAD_LOOP 10000 int counter = 0; int run(void* data) { for (int i = 0; i < THREAD_LOOP; i++) counter++; // <- each thread would modify the global variable counter here. printf("Thread %d terminates.\n", *((int*) data)); return thrd_success; } int main(void) { #ifndef __STDC_NO_THREADS__ int ids[THREAD_COUNT]; thrd_t threads[THREAD_COUNT]; for (int i = 0; i < THREAD_COUNT; i++) { ids[i] = i + 1; thrd_create(&threads[i], run, ids + i); } for (int i = 0; i < THREAD_COUNT; i++) thrd_join(threads[i], NULL); printf("Counter value is: %d.\n", counter); #endif return 0; }

Obtuve una instantánea del código ensamblador de la función de ejecución como se muestra a continuación, y también señalé el código correspondiente para counter++ .

ingrese la descripción de la imagen aquí

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

¿Significa que el x86 o el compilador podrían garantizar que cada modificación en una variable int sea segura para subprocesos?

No , en las plataformas x86/x86-64 esto no es seguro para subprocesos (como en la mayoría de las plataformas). El código ensamblador prueba que la operación no se realiza atómicamente.

O algo malo con mi programa?

Bueno, posiblemente . No se garantiza que los subprocesos se ejecuten en el momento. Si el sistema operativo tarda algún tiempo en crear cada subproceso, el bucle puede ejecutarse en serie. 10000 iteraciones no es mucho y los principales procesadores modernos pueden ejecutar el bucle en muy poco tiempo (p. ej., unos pocos microsegundos), normalmente menos del tiempo necesario para crear nuevos subprocesos . Puede mitigar el problema utilizando más iteraciones y una barrera .

No vi ningún caso de que el valor impreso sea incorrecto (200000).

Este no es el caso en mi máquina que no utiliza subprocesos múltiples simultáneos (por ejemplo, HyperThreading). Esto muestra que el problema depende de la ejecución o del hardware.

¿Es posible que este problema se relacione con el hecho de que lo ejecuté en una CPU de un solo núcleo?

Sí , de hecho.

La condición de carrera proviene principalmente del hecho de que un núcleo puede solicitar una línea de caché dada que es utilizada por otro subproceso. El valor obtenido podría no estar actualizado. En plataformas x86/x86-64, cuando un núcleo escribe en una línea de caché, invalida la copia en otros núcleos. Sin embargo, todavía causa un problema porque la operación no se realiza atómicamente.

Si solo usa 1 núcleo y 1 subproceso de hardware, entonces los subprocesos de software se ejecutan en serie (de manera intercalada) durante un cuanto determinado, que probablemente sea mucho más grande que el tiempo para ejecutar el ciclo . En este caso, esto significa que la ejecución general es secuencial y no debería haber ningún problema. Si el cuanto es menor que el tiempo para ejecutar el ciclo, entonces el problema debería aparecer ya que el hilo puede interrumpirse en el medio del ciclo (y el valor obtenido será modificado por otros hilos mientras tanto).

Puede usar numactl --physcpubind=0 en Linux para anclar su proceso a un núcleo determinado. En mi máquina, puedo confirmar que el problema no aparece si solo se usa un núcleo . Sin embargo, sí aparece con al menos 2 núcleos. Si también establezco THREAD_LOOP en un valor 10000 veces mayor, los resultados ya no son los mismos. Esto confirma la hipótesis cuántica explicada anteriormente.

over 4 years ago · Santiago Trujillo Denunciar

0

¿Significa que el x86 o el compilador podrían garantizar que cada modificación en una variable int sea segura para subprocesos?

No. Que algo funcione cuando lo probó no significa que haya una garantía, nunca .

O algo malo con mi programa?

Sí, su programa tiene una carrera de datos. Solucione el error y el misterio desaparecerá.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda