2009-08-27 26 views
6

En C, declarar una variable estática en el ámbito global lo convierte en una variable global. ¿Esta variable global se comparte entre hilos o se asigna por hilo?C global estático - compartido entre hilos?

Actualización: Si se comparten entre subprocesos, ¿cuál es una manera fácil de hacer globales en una biblioteca preexistente exclusiva de un subproceso/no compartida?

Update2: Básicamente, necesito usar una biblioteca C preexistente con globales en una manera segura para subprocesos.

+4

Declarar una variable estática lo convierte en una variable de alcance de archivo. Declararlo no estático lo hace global. –

+0

Gracias por esa aclaración. – jameszhao00

+0

¿Qué sistema operativo usas? Creo que podría haber una solución específica de plataforma para Update2. –

Respuesta

16

Es visible para todo el proceso, es decir, todos los hilos. Por supuesto, esto es en la práctica. En teoría, no se podría decir porque los hilos no tienen nada que ver con el estándar C (al menos hasta c99, que es el estándar que estaba en vigor cuando se formuló esta pregunta).

Pero todas las bibliotecas de hilos que he usado tendrían acceso global a todos los hilos.


Actualización 1:

Muchas bibliotecas de hebras (threads, por ejemplo) le permitirá crear datos de hilos específica, un medio para funciones para crear y utilizar los datos específicos de la rosca sin tener pasó a través de la función.

Así que, por ejemplo, una función para devolver números pseudoaleatorios puede querer que cada subproceso tenga una semilla independiente. Así que cada vez que se lo llama o bien crea o se conecta a un bloque específico de subprocesos que contiene esa semilla (usando algún tipo de clave).

Esto permite que las funciones mantengan la misma firma que las no roscadas (importante si son funciones ISO C por ejemplo) ya que la otra solución implica agregar un puntero específico de hilo a la llamada a la función.

Otra posibilidad es tener un conjunto de variables globales de los cuales cada hilo obtiene uno, tales como:

int fDone[10]; 
int idx; 
: : : 
for (i = 0; i < 10; i++) { 
    idx = i; 
    startThread (function, i); 
    while (idx >= 0) 
     yield(); 
} 

void function() { 
    int myIdx = idx; 
    idx = -1; 
    while (1) { 
     : : : 
    } 
} 

Esto permitiría a la función del hilo que se les diga qué variable global en la matriz pertenece a ella .

Existen otros métodos, sin duda, pero a falta de conocer su entorno objetivo, no tiene mucho sentido discutirlos.


Actualización 2:

La manera más fácil utilizar una biblioteca no seguro para subprocesos en un entorno roscado es proporcionar llamadas envoltorio con protección mutex.

Por ejemplo, supongamos que su biblioteca tiene una función doThis() no segura para subprocesos. Lo que se hace es proporcionar un contenedor para que:

void myDoThis (a, b) { 
    static mutex_t serialize; 
    mutex_claim (&serialize); 
    doThis (a, b); 
    mutex_release (&serialize); 
} 

lo que sucederá es que hay sólo un hilo a la vez será capaz de reclamar la exclusión mutua (y por tanto llamar a la función no-thread-safe). Otros serán bloqueados hasta que regrese el actual.

+0

Gracias. Pregunta actualizada un poco. – jameszhao00

+0

Lo siento. Actualizado de nuevo ... – jameszhao00

+0

Está bien, James, creo que estoy pendiente por ahora :-) – paxdiablo

1

El estándar C/C++ no admite subprocesos. Entonces, todas las variables se comparten entre hilos. Soporte de subprocesos implementado en la biblioteca de tiempo de ejecución C/C++ que no es parte del estándar. Runtime es específico para cada implementación de C/C++. Si desea escribir código portátil en C++, puede usar boost interprocess library.

Para declarar la variable local de subprocesos en Microsoft Visual Studio puede usar la palabra clave específica de Microsoft __declspec(thread).

1

Como se menciona en @Pax, las variables estáticas son visibles para todos los hilos. No hay una construcción de datos C++ asociada con un hilo en particular.

Sin embargo, en Windows puede usar la API TlsAlloc para asignar un índice para datos específicos de subprocesos y poner ese índice en una variable estática. Cada hilo tiene su propia ranura a la que puede acceder utilizando este índice y TlsGetValue y TlsSetValue. Para obtener más información, lea acerca de Using Thread Local Storage en MSDN.

Actualización: No hay forma de que los globales en una biblioteca preexistente sean específicos de subprocesos. Cualquier solución requeriría que modifiques el código también para saber que los datos tienen afinidad por el hilo.

Cuestiones relacionadas