2009-04-13 19 views
6

hago el siguiente razonamiento, por favor, dime lo que está mal (o derecha) al respecto:¿Las funciones en línea en C/C++ son una forma de hacerlas seguras para subprocesos?

"Si inlining una función duplica el código en el lugar se llama la función, las variables estáticas y locales están duplicados para cada función que lo llama y si solo hay un hilo ejecutando la función que llama al encriptado al mismo tiempo, entonces el código es seguro para subprocesos ".

"Y, si no ayuda con las variables estáticas y globales, ¿lo hace con un código que crea variables temporales?"

Gracias

+0

Las variables locales de una función siempre se duplican para cada instancia de la función que se está ejecutando. –

+2

No es así si una variable se declara estática. Las variables estáticas retienen valores entre llamadas de función y no están duplicadas. – sharptooth

+1

Bien, entendido. Las variables locales se ponen en la pila, ¿verdad? – alvatar

Respuesta

25

Cuando declara una función como en línea, es simplemente una sugerencia para el compilador. Las variables estáticas tienen una definición clara en el lenguaje. Si el compilador integra la función, aún está obligado a mantener las variables estáticas compartidas entre todas las instancias de la función. Por lo tanto, seguirán siendo globales y deben estar protegidos en un entorno MT.

En cuanto a las variables locales, a menos que se usen fuera de la función, son seguras para hilos independientemente de si la función está en línea o no.

+2

declaración en línea puede ser una pista, sin embargo __forceinline se fuerza en MSVC;) – RandomNickName42

28

No, estás equivocado. Para una variable estática, ya sea en línea o no, solo hay una instancia. Las funciones en línea no tienen ningún efecto en la seguridad del hilo, de una manera u otra.

2

Existen (o tal vez fueron) compiladores con errores que duplican variables estáticas para cada alineación de la función contenedora. Este no es el comportamiento previsto.

Con un compilador que cumple con los estándares, tiene la garantía de tener una instancia de cada variable estática independientemente de la alineación y usted mismo debe encargarse de la seguridad de los hilos.

6

Cada hilo obtiene su propia copia de los objetos locales, por lo que no puede haber ningún problema relacionado con enhebrarlos, ya sea que lo haga en línea o no.

Pero si está accediendo a una variable estática o miembro de la clase, todos los problemas relacionados con el multihilo (corromper la variable, actualización perdida ...) seguirán allí, independientemente de si está en línea o no.

1

entrante no tiene efecto sobre si una función es segura o no. Por ejemplo:

inline void doTheThing() 
{ 
    int a = 42; // this is thread safe, but it would be anyway 
    vector<int> * answers = getTheAnswers(); // this is not thread safe 
} 

El acceso al vector apuntado por getTheAnswers() no se enrosque seguro porque no hay código de la prevención de cualquier otro hilo de la ejecución del código. Hacer que la función en línea no impida que doThing() sea llamado por múltiples hilos al mismo tiempo. Para hacer seguro el subproceso doTheThing(), debe asegurarse de que no se invoque en paralelo o que los datos compartidos (no locales) a los que acceda estén protegidos.

+0

No dije que era inseguro de subprocesos; Dije que no era seguro para subprocesos. Eso no es cortar los pelos. Comprender la diferencia entre la seguridad de los subprocesos, inseguro y no seguro es la diferencia entre las personas que asimilan multithreading y las que no. –

+0

A menos que sepa la implementación de getTheAnswers(), no puede decir que es seguro para subprocesos. La firma implícita en la llamada (vector * getTheAnswers;) ciertamente no sugiere que lo sea. –

+0

OK, entonces sugiere algo para usted: que asigna un vector y lo devuelve. Que puede o no ser verdad. Pero incluso si fuera cierto, ¿cómo lo hace? ¿Copia elementos de algún vector global? ¿El acceso de ese vector global es seguro? El punto es: usted no sabe. –

2

Thread safety no tiene nada que ver con inlining. El hecho de que cada hilo ejecute una copia del mismo código no hace que sea seguro acceder a los datos compartidos. Asegúrese de leer en Thread safety antes de comenzar la programación con múltiples hilos.

+0

respuesta no útil. – alvatar

+1

¿Por qué? La única forma de programar la seguridad de subprocesos es aprender sobre seguridad de subprocesos. Y por lo que puedo ver, mi respuesta es, a partir de ahora, la única que le proporciona un enlace a algunas lecturas para obtener una comprensión más profunda del asunto. – lothar

+0

Sí, tienes razón en que me das un enlace. Pero para un artículo de wikipedia sobre seguridad de subprocesos no necesito preguntar en SO. Además, pregunto las razones. De todos modos, eliminé mi voto negativo. – alvatar

2

Si yo fuera usted, no usaría variables estáticas dentro de las funciones en línea. Las versiones anteriores del estándar C++ requerían un significado diferente al actual.

0

No, en absoluto.

Para que sea seguro para subprocesos, una función debe ser segura para subprocesos con respecto a CUALQUIER instancia de la función, incluido él mismo; varios hilos pueden ejecutar la misma instancia de una función en línea al mismo tiempo.

Por lo tanto, incluso si el compilador hizo lo que usted sugirió (que no debería, como han dicho otros), eso no lo haría seguro para subprocesos.

-2

Todas las variables estáticas en las funciones (normal y en línea) entran en el montón. El montón es NO HILO SEGURO.

3

La alineación y la seguridad de la rosca son ortogonales, es decir, conceptos no relacionados.

Considere estas funciones:

 
int factorial(const int n) 
{ 
    if (n <= 1) 
    { 
    return 1; 
    } 

    return factorial(n - 1); 
} 

Esta función no puede ser inline ya que es recursivo, sin embargo, es perfectamente seguro para subprocesos.

 
int factorial_2(int n) 
{ 
    int Result = 1; 

    while (n > 1) 
    { 
    Result *= n--; 
    } 

    return Result; 
} 

Esta función podría ser inline por el compilador, y sigue siendo perfectamente seguro para subprocesos.

 
int RefCount; 

void DecRef() 
{ 
    --RefCount; 
} 

Esta función no es segura para subprocesos, independientemente de si el compilador lo indica o no.

+0

gracias por esta respuesta tardía :). Ahora tengo conceptos claros en mi mente, pero su código es muy ilustrativo. ¡Gracias! – alvatar

+0

Ha sido un placer :) – Tobias

3

Las versiones anteriores de C++ (y la versión actual de C) no reconocen el concepto de subprocesos. Simplemente no es parte del estándar. Por lo tanto, confiar en la optimización del compilador para hacer que su código sea seguro para la ejecución de subprocesos no es una buena idea.

Cuestiones relacionadas