Domanda

Ho variabili statiche globali in una libreria C, che generano eccezioni in un'esecuzione multithread.Devo renderli sicuri in qualche modo (vale a dire, ogni thread dovrebbe riguardare un'istanza diversa di queste variabili).Qualche metodo consigliato?

È stato utile?

Soluzione

Non esiste un modo standard che funzioni in tutte le implementazioni C, ma esistono soluzioni specifiche dell'implementazione. Ad esempio, con il compilatore di Microsoft (vedi i documenti),

__declspec( thread ) int tls_i = 1;

fa tls_i Live in thread-local Storage (ogni thread ha la propria istanza separata di questa variabile). Insieme a GCC, la sintassi è

__thread int tls_i;

Potresti anche voler controllare il ingresso di Wikipedia a questo proposito.

Altri suggerimenti

Prima domanda:

  • i thread necessitano delle proprie copie delle variabili?
  • oppure devono coordinare l'accesso a un'unica copia condivisa?

Se hai bisogno del primo, le altre risposte hanno fornito suggerimenti sulla "archiviazione locale del thread".

Se hai bisogno di quest'ultimo, in un modo o nell'altro devi assicurarti che ci sia un mutex appropriato su quelle variabili (l'ambito del mutex è uno dei problemi che devi affrontare) e che tutti i thread utilizzino il mutex e rilascino il mutex.Questo è più complicato.Potrebbe anche essere necessario fornire funzioni che controllino l'accesso alle variabili.

La variabile standard errno può essere un lvalue modificabile:

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

In un'applicazione threaded (compilata con -DREENTRANT), questo è ciò che accade;su MacOS X, sembra che ciò accada comunque (utilizzano il nome __error invece di _errno_func;entrambi sono nello spazio dei nomi dell'implementazione).

Potresti voler, o finire per dover, fare qualcosa di simile per le tue variabili.Il fatto che tu dica che sono statici migliora un po' le cose.Hai solo un file da gestire (a meno che tu non sia abbastanza distratto da passare indietro o attivare puntatori a quelle variabili).

Ciò di cui hai bisogno è TLS (thread Local Storage), che è anche noto come Dati specifici del thread o Dati thread-private. Questo meccanismo può garantire a ciascun thread di accedere alla propria copia separata dei dati, senza preoccuparsi di sincronizzare l'accesso con altri thread.


Esistono due metodi per utilizzare TLS:

  1. implicito: usando la parola chiave

    Finestre: __declspec (thread) int tls_var = 10;

    Linux con GCC: __Thread int tls_var = 10

  2. esplicito: usando API relativa a TLS specifica

    Finestre:

      Tlsalloc (): allocare la memoria per i dati TLS
      Tlsfree (): liberare la memoria dei dati TLS
      TlssetValue (): Imposta il valore di TLS
      TlsgetValue (): Ottieni il valore di TLS

    Fare riferimento a MSDN per informazioni dettagliate.

    Linux con GCC:

      pThread_key_create (): Crea i dati TLS
      pThread_key_delete (): Destory i dati TLS
      pThread_getSpecific (): ottieni il valore di TLS
      pThread_setspecific(): imposta il valore di TLS
    Trasformarsi alla mannatura per informazioni specifiche e dettagliate.

La maggior parte dei compilatori ha un modo di designare l'archiviazione dei fili locali. Supponendo che sia disponibile, è quello che vuoi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top