sirven que punteros puntero programacion parametros para los funciones estructura ejemplos datos como cadenas arreglos aritmetica apuntadores go concurrency goroutine

go - punteros - ¿Es seguro leer un puntero de función al mismo tiempo sin un bloqueo?



punteros y arreglos en c (2)

El acceso concurrente no sincronizado a cualquier variable desde múltiples rutinas en las que al menos una de ellas es una escritura es un comportamiento indefinido de The Go Memory Model .

Indefinido significa lo que dice: indefinido . Puede ser que su programa funcione correctamente, puede ser que funcione incorrectamente. Puede provocar la pérdida de memoria y la seguridad de tipo proporcionada por el tiempo de ejecución Go (consulte el ejemplo a continuación). Incluso puede bloquear su programa. O incluso puede hacer que la Tierra explote (la probabilidad de eso es extremadamente pequeña, tal vez incluso menor que 1e-40, pero aún así ...).

Esto no está definido en su caso significa que sí, puedo ser nil , parcialmente asignado, inválido, indefinido, ... cualquier otra cosa que no sea ao b . Esta lista es solo un pequeño subconjunto de todos los resultados posibles.

Deja de pensar que algunas carreras de datos son (o pueden ser) benignas o inofensivas. Pueden ser la fuente de las peores cosas si no se atienden.

Como su código escribe en la variable a en una rutina y la lee en otra (que intenta asignar su valor a otra variable i ), es una carrera de datos y, como tal, no es segura. No importa si en sus pruebas funciona "correctamente". Uno podría tomar su código como punto de partida, ampliarlo / construir sobre él y provocar una catástrofe debido a su carrera de datos inicialmente "no perjudicial".

Como preguntas relacionadas, lea ¿Qué tan seguros son los mapas de Golang para operaciones concurrentes de lectura / escritura? y sincronización incorrecta en go lang .

Se recomienda encarecidamente leer la publicación de blog de Dmitry Vyukov: Razas de datos benignas: ¿qué podría salir mal?

También una publicación de blog muy interesante que muestra un ejemplo que rompe la seguridad de la memoria de Go con una carrera de datos intencional: las carreras de datos de Golang para romper la seguridad de la memoria

Supongamos que tengo esto:

go func() { for range time.Tick(1 * time.Millisecond) { a, b = b, a } }()

Y en otra parte:

i := a // <-- Is this safe?

Para esta pregunta, no es importante cuál es el valor de i con respecto al original a o b . La única pregunta es si leer a libro es seguro. Es decir, ¿es posible que a sea nil , parcialmente asignado, inválido, indefinido, ... algo más que un valor válido?

He intentado que falle, pero hasta ahora siempre tiene éxito (en mi Mac).

No he podido encontrar nada específico más allá de esta cita en el documento The Go Memory Model :

Las lecturas y escrituras de valores mayores que una sola palabra de máquina se comportan como múltiples operaciones del tamaño de palabras de máquina en un orden no especificado.

¿Esto implica que una sola escritura de palabras de máquina es efectivamente atómica? Y, si es así, ¿se escribe el puntero de función en Ir a una sola operación de palabra de máquina?

Actualización: aquí hay una solución correctamente sincronizada


En términos de condición de carrera , no es seguro. En resumen, mi comprensión de la condición de la carrera es cuando hay más de una rutina asincrónica (corutinas, hilos, procesos, gorutinas, etc.) que intentan acceder al mismo recurso y al menos una es una operación de escritura, por lo que en su ejemplo tenemos 2 Goroutines leyendo y escribiendo variables de tipo de función, creo que lo que importa desde un punto de vista concurrente es que esas variables tienen un espacio de memoria en algún lugar y estamos tratando de leer o escribir en esa porción de memoria.

Respuesta corta : simplemente ejecute su ejemplo usando el indicador -race con go run -race o go build -race y verá una carrera de datos detectada.