Pergunta

Tenho variáveis ​​estáticas globais em uma biblioteca C, que geram exceções em uma execução multithread.Preciso torná-los seguros de alguma forma (ou seja, cada thread deve estar relacionado a uma instância diferente dessas variáveis).Algum método recomendado?

Foi útil?

Solução

Não existe uma maneira padrão que funcione em todas as implementações C, mas existem soluções específicas para implementações.Por exemplo, com o compilador da Microsoft (veja os documentos),

__declspec( thread ) int tls_i = 1;

faz tls_i reside no armazenamento local de thread (cada thread tem sua própria instância separada desta variável).Com gcc, a sintaxe é

__thread int tls_i;

Você também pode querer verificar o entrada da Wikipédia sobre o assunto.

Outras dicas

Primeira pergunta:

  • os threads precisam de suas próprias cópias das variáveis?
  • ou eles precisam coordenar o acesso a uma única cópia compartilhada?

Se você precisar do primeiro, as outras respostas fizeram sugestões sobre 'armazenamento local de thread'.

Se você precisar do último, então, de uma forma ou de outra, você precisa garantir que haja um mutex apropriado nessas variáveis ​​​​(o escopo do mutex é um dos problemas que você enfrenta) e que todos os threads usam o mutex e liberam o mutex.Isso é mais complicado.Pode até ser que você precise fornecer funções que controlem o acesso às variáveis.

A variável padrão errno pode ser um lvalue modificável:

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

Em um aplicativo threaded (compilado com -DREENTRANT), é isso que acontece;no MacOS X, parece que é o que acontece de qualquer maneira (eles usam o nome __error em vez de _errno_func;ambos estão no namespace da implementação).

Você pode querer, ou acabar tendo que fazer algo semelhante para suas variáveis.O fato de você dizer que eles são estáticos melhora um pouco as coisas.Você só tem um arquivo para lidar (a menos que seja descuidado o suficiente para passar de volta - ou em - ponteiros para essas variáveis).

O que você precisava é TLS (armazenamento local de thread), que também é conhecido como dados específicos do thread ou dados privados do thread.Esse mecanismo pode garantir que cada thread acesse sua própria cópia separada de dados, sem se preocupar em sincronizar o acesso com outros threads.


Existem dois métodos para usar TLS:

  1. implícito:usando palavra-chave

    Janelas: __declspec(thread) int tls_var = 10;

    Linux com GCC: __thread int tls_var = 10

  2. explícito:usando API específica relacionada a TLS

    Janelas:

      TlsAlloc(): alocar memória para dados tls
      TlsFree(): liberar a memória dos dados tls
      TlsSetValue(): definir o valor de tls
      TlsGetValue(): obter o valor de tls

    Consulte o MSDN para obter informações detalhadas.

    Linux com GCC:

      pthread_key_create():crie os dados tls
      pthread_key_delete():destruir os dados tls
      pthread_getspecific():obter o valor de tls
      pthread_setespecífico():definir o valor de tls
    Consulte a página de manual para obter informações específicas e detalhadas.

A maioria dos compiladores tem alguma maneira de designar armazenamento local de thread.Supondo que esteja disponível, é isso que você deseja.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top