2011-09-30 24 views
19

¿Cómo se definen las variables estáticas locales (que mantiene su valor entre las llamadas a funciones) que no se comparten entre diferentes subprocesos?¿Cómo se definen las variables estáticas locales locales de subprocesos?

Busco una respuesta tanto en C y C++

+0

¿Qué sistema operativo está utilizando? TLS no es portátil entre unixen y Windows. – bdonlan

+3

C++ 11 introduce otra duración de almacenamiento llamada ['thread_local'] (http://en.cppreference.com/w/cpp/language/storage_duration). Intenta usarlo. – Nawaz

+0

OS es Windows ... –

Respuesta

9

en Windows mediante Windows API: TlsAlloc()/TlsSetValue()/TlsGetValue()

en Windows usando el compilador intrínseca: utilizar _declspec(thread)

en Linux (otra POSIX? ??): get_thread_area() y relacionado

+0

después de leer en MSDN, las funciones de Tls son exactamente lo que estaba buscando. –

+2

has olvidado TlsFree :-) –

2

El C estándar actual no tiene un modelo de hilos o similares, por lo que no puede obtener una respuesta, no.

La utilidad prevista por POSIX para eso es pthread_[gs]etspecific.

La próxima versión del estándar C agrega subprocesos y tiene un concepto de almacenamiento local de subprocesos.

-3

Puede crear la estructura de datos asignada desde el montón para cada subproceso.

Ejemplo:

struct ThreadLocal 
{ 
    int var1; 
    float var2; 
    //etc.. 
} 
8

Solo use static y __thread en su función.

Ejemplo:

int test(void) 
{ 
     static __thread a; 

     return a++; 
} 
+3

es __thread standard? –

+2

@ Ali: no, es una extensión proporcionada por GCC y algunos otros compiladores. En MSVC, creo que usas '__declspec (thread)' en su lugar. –

+3

__thread funciona en linux, bsd, aix, y con xl_c, gcc y muchos otros compiladores. puede ser trivialmente #defined a __declspec (thread) en windows. –

1

Usted puede hacer su propio hilo de almacenamiento local específico como Singleton por ID del hilo. Algo como esto:

struct ThreadLocalStorage 
{ 
    ThreadLocalStorage() 
    { 
     // initialization here 
    } 
    int my_static_variable_1; 
    // more variables 
}; 

class StorageManager 
{ 
    std::map<int, ThreadLocalStorage *> m_storages; 

    ~StorageManager() 
    { // storage cleanup 
     std::map<int, ThreadLocalStorage *>::iterator it; 
     for(it = m_storages.begin(); it != m_storages.end(); ++it) 
      delete it->second; 
    } 

    ThreadLocalStorage * getStorage() 
    { 
     int thread_id = GetThreadId(); 
     if(m_storages.find(thread_id) == m_storages.end()) 
     { 
      m_storages[thread_id] = new ThreadLocalStorage; 
     } 

     return m_storages[thread_id]; 
    } 

public: 
    static ThreadLocalStorage * threadLocalStorage() 
    { 
     static StorageManager instance; 
     return instance.getStorage(); 
    } 
}; 

GetThreadId(); es una función específica de la plataforma para determinar la identificación del hilo de la persona que llama. Algo como esto:

int GetThreadId() 
{ 
    int id; 
#ifdef linux 
    id = (int)gettid(); 
#else // windows 
    id = (int)GetCurrentThreadId(); 
#endif 
    return id; 
} 

Ahora, dentro de una función del hilo que se puede utilizar es el almacenamiento local:

void threadFunction(void*) 
{ 
    StorageManager::threadLocalStorage()->my_static_variable_1 = 5; //every thread will have 
                  // his own instance of local storage. 
} 
+0

También necesitará la sincronización (como un mutex de lectura/escritura) para proteger 'm_storages' del acceso por múltiples hilos. –

+0

por supuesto. estás en lo correcto. – GreenScape

+0

No solo m_storages, sino también std :: map y la "instancia de StorageManager estático local"; no es seguro para subprocesos En código nativo, implementar un singleton de alta eficiencia no es una tarea fácil, ver "C++ y los peligros del bloqueo doblemente controlado" por Scott Meyers y Andrei Alexandrescu. http://erdani.com/publications/DDJ_Jul_Aug_2004_revised.pdf – zhaorufei

2

También puede utilizar los C++ 11 hilo adiciones de almacenamiento local si tiene acceso a C++ 11.

Cuestiones relacionadas