¿Existen reglas / pautas generales para lo que hace que un método sea seguro para subprocesos? Entiendo que probablemente haya un millón de situaciones puntuales, pero ¿qué pasa en general? ¿Es así de simple?
- Si un método solo accede a variables locales, es seguro para subprocesos.
¿Es asi? ¿Se aplica eso también a los métodos estáticos?
Una respuesta, proporcionada por @Cybis, fue:
Las variables locales no se pueden compartir entre subprocesos porque cada subproceso tiene su propia pila.
¿Es ese el caso de los métodos estáticos también?
Si se pasa un método a un objeto de referencia, ¿eso rompe la seguridad del hilo? He investigado un poco, y hay mucho sobre ciertos casos, pero esperaba poder definir, usando solo unas pocas reglas, pautas a seguir para asegurarme de que un método sea seguro para subprocesos.
Entonces, supongo que mi última pregunta es: "¿Existe una breve lista de reglas que definen un método seguro para subprocesos? Si es así, ¿cuáles son?"
EDITAR
Aquí se han hecho muchos puntos buenos. Creo que la verdadera respuesta a esta pregunta es: "No hay reglas simples para garantizar la seguridad de los hilos". Frio. Multa. Pero, en general , creo que la respuesta aceptada proporciona un buen resumen breve. Siempre hay excepciones. Que así sea. Puedo vivir con ello.
fuente
Respuestas:
Si un método (instancia o estático) solo hace referencia a variables dentro de ese método, entonces es seguro para subprocesos porque cada subproceso tiene su propia pila:
En este caso, varios subprocesos podrían llamar
ThreadSafeMethod
simultáneamente sin problemas.Esto también es cierto si el método llama a otro método de clase que solo hace referencia a variables de ámbito local:
Si un método accede a propiedades o campos (estado del objeto) (instancia o estático), entonces debe usar bloqueos para asegurarse de que los valores no sean modificados por un hilo diferente.
Debe tener en cuenta que cualquier parámetro pasado al método que no sea una estructura o sea inmutable podría ser mutado por otro hilo fuera del alcance del método.
Para garantizar la concurrencia adecuada, debe usar el bloqueo.
Para obtener más información, consulte la referencia de C # de la declaración de bloqueo y ReadWriterLockSlim .
lock es principalmente útil para proporcionar una funcionalidad a la vez,
ReadWriterLockSlim
es útil si necesita múltiples lectores y escritores individuales.fuente
private string someValue;
no esstatic
así, cada instancia obtendrá una copia separada de esa variable. Entonces, ¿puede explicar cómo esto no es seguro para subprocesos?Thing
clase a la que acceden varios subprocesosAbsolutamente no. Puede escribir un programa con solo una variable local a la que se acceda desde un solo subproceso que, sin embargo, no sea seguro para subprocesos:
https://stackoverflow.com/a/8883117/88656
Absolutamente no.
Absolutamente no. La característica distintiva de una variable local es que solo es visible desde el ámbito local , no que está asignada en el grupo temporal . Es perfectamente legal y posible acceder a la misma variable local desde dos hilos diferentes. Puede hacerlo utilizando métodos anónimos, lambdas, bloques iteradores o métodos asíncronos.
Absolutamente no.
Tal vez.
Tendrás que aprender a vivir con desilusión. Este es un tema muy difícil.
No Como viste en mi ejemplo anterior, un método vacío puede no ser seguro para subprocesos . También podría preguntar "¿hay una breve lista de reglas que garantice que un método sea correcto "? No no hay. La seguridad de los hilos no es más que un tipo de corrección extremadamente complicado.
Además, el hecho de que esté haciendo la pregunta indica su malentendido fundamental sobre la seguridad del hilo. La seguridad de subprocesos es una propiedad global , no local de un programa. La razón por la cual es tan difícil hacerlo bien es porque debe tener un conocimiento completo del comportamiento de enhebrado de todo el programa para garantizar su seguridad.
Nuevamente, mira mi ejemplo: cada método es trivial . Es la forma en que los métodos interactúan entre sí a un nivel "global" lo que hace que el programa se bloquee. No puede ver cada método y marcarlo como "seguro" y luego esperar que todo el programa sea seguro, como tampoco puede concluir que debido a que su casa está hecha de ladrillos 100% no huecos, la casa también es segura. no hueco El vacío de una casa es una propiedad global de todo, no un agregado de las propiedades de sus partes.
fuente
class C { public static Func<int> getter; public static Action<int> setter; public static void M() { int x = 0; getter = ()=>x; setter = y=>{x=y;};} }
llame a M (), luego llame a C.getter y C.setter en dos hilos diferentes. La variable local ahora se puede escribir y leer en dos subprocesos diferentes aunque sea local. Nuevamente: la característica definitoria de una variable local es que es local , no que está en la pila del hilo .No hay una regla dura y rápida.
Aquí hay algunas reglas para hacer que el hilo de código sea seguro en .NET y por qué estas no son buenas reglas:
lock
en una cosa común. Todos los bloqueos deben hacerse en el mismo orden. Esto hará que el hilo del código sea seguro, pero será increíblemente lento, y es mejor que no uses múltiples hilos.No hay ninguna regla que haga que el hilo del código sea seguro, lo único que puede hacer es asegurarse de que su código funcione, no importa cuántas veces se ejecute activamente, cada hilo puede interrumpirse en cualquier momento, con cada hilo en su propio estado / ubicación, y esto para cada función (estática o no) que está accediendo a objetos comunes.
fuente
Debe estar sincronizado, utilizando un bloqueo de objeto, sin estado o inmutable.
enlace: http://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html
fuente