Pregunta

Tengo variables estáticas globales en una biblioteca C, que generan excepciones en una ejecución múltiple. Necesito hacerlos seguros de alguna manera (es decir, cada hilo debe relacionarse con una instancia diferente de estas variables). ¿Algún método recomendado?

¿Fue útil?

Solución

No existe una forma estándar que funcione en todas las implementaciones de C, pero existen soluciones específicas de implementación. Por ejemplo, con el compilador de Microsoft (ver los documentos),

__declspec( thread ) int tls_i = 1;

hace tls_i Live en el almacenamiento de hilo-local (cada hilo tiene su propia instancia separada de esta variable). Con GCC, la sintaxis es

__thread int tls_i;

También es posible que desee verificar el Entrada de Wikipedia sobre el tema.

Otros consejos

Primera pregunta:

  • ¿Los hilos necesitan sus propias copias de las variables?
  • ¿O necesitan coordinar el acceso a una sola copia compartida?

Si necesita el primero, las otras respuestas han hecho sugerencias sobre el 'almacenamiento local de hilos'.

Si necesita este último, de alguna manera u otro debe asegurarse de que haya un mutex apropiado en esas variables (el alcance del mutex es uno de los problemas que enfrenta), y que todos los hilos usan el mutex y liberan el mutex. Esto es más complicado. Incluso puede ser que necesite proporcionar funciones que controlen el acceso a las variables.

La variable estándar errno puede ser un LValue modificable:

extern int *_errno_func(void);
#define errno (*(_errno_func)())

En una aplicación roscada (compilada con -dreentrant), esto es lo que sucede; En MacOS X, parece ser lo que sucede de todos modos (usan el nombre __error en vez de _errno_func; Ambos están en el espacio de nombres de la implementación).

Es posible que desee o termine teniendo que hacer algo similar para sus variables. El hecho de que digas que son estáticos mejora un poco las cosas. Solo tiene un archivo con el que tratar (a menos que sea lo suficientemente descuidado como para retroceder o encender a esas variables).

Lo que necesitabas es TLS (almacenamiento local de subprocesos), que también se conoce como datos específicos de hilo o datos-privados de hilo. Este mecanismo puede garantizar que cada hilo acceda a su propia copia separada de datos, sin preocuparse por sincronizar el acceso con otros hilos.


Hay dos métodos para usar TLS:

  1. Implícito: Uso de la palabra clave

    Windows: __DeclSpec (Thread) int tls_var = 10;

    Linux con GCC: __Thread int tls_var = 10

  2. Explícito: usando una API relacionada con TLS específica

    Windows:

      Tlsalloc (): Asignar memoria para los datos de TLS
      Tlsfree (): liberar la memoria de los datos de TLS
      TlssetValue (): Establecer el valor de TLS
      TlsgetValue (): Obtener el valor de TLS

    Consulte MSDN para obtener información detallada.

    Linux con GCC:

      pthread_key_create (): Cree los datos de TLS
      pthread_key_delete (): Destory Los datos de TLS
      pthread_getSpecific (): Obtener el valor de TLS
      pthread_setspecífico(): establecer el valor de TLS
    Vaya a la mano de mano para obtener información específica y detallada.

La mayoría de los compiladores tienen alguna forma de designar el almacenamiento local de subprocesos. Suponiendo que está disponible, eso es lo que quieres.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top