Обеспечение безопасности многопоточных глобальных статических переменных - PullRequest
6 голосов
/ 18 апреля 2010

У меня есть глобальные статические переменные в библиотеке C, которые генерируют исключения при многопоточном запуске. Мне нужно каким-то образом сделать их безопасными (то есть каждый поток должен относиться к отдельному экземпляру этих переменных). Любые рекомендуемые методы?

Ответы [ 4 ]

10 голосов
/ 18 апреля 2010

Не существует стандартного способа, который работал бы во всех реализациях C, но существуют решения для конкретной реализации. Например, с компилятором Microsoft (см. документы ),

__declspec( thread ) int tls_i = 1;

делает tls_i живым в локальном хранилище потока (каждый поток имеет свой отдельный экземпляр этой переменной). С gcc синтаксис

__thread int tls_i;

Вы также можете проверить запись в википедии по теме.

4 голосов
/ 18 апреля 2010

Первый вопрос:

  • нужны ли потокам собственные копии переменных?
  • или они должны координировать доступ к одной общей копии?

Если вам нужно первое, в других ответах содержатся предложения о «локальном хранилище потока».

Если вам нужно второе, то так или иначе вам нужно убедиться, что на этих серверах есть соответствующий мьютекс.переменные (область мьютекса - одна из проблем, с которой вы сталкиваетесь), и что все потоки используют мьютекс и освобождают мьютекс.Это сложнее.Может даже оказаться, что вам нужно предоставить функции, управляющие доступом к переменным.

Стандартная переменная errno может быть изменяемым значением lvalue:

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

В многопоточном приложении (скомпилированос -DREENTRANT), это то, что происходит;в MacOS X, похоже, так и происходит (они используют имя __error вместо _errno_func; оба находятся в пространстве имен реализации).

Возможно, вы захотите или в конечном итоге должнысделать что-то подобное для ваших переменных.Тот факт, что вы говорите, что они статичны, немного улучшает ситуацию.У вас есть только один файл для работы (если вы не достаточно небрежны, чтобы передавать или указывать на эти переменные).

3 голосов
/ 08 сентября 2010

Что вам нужно, это TLS (локальное хранилище потока) , которое также известно как данные, специфичные для потока или данные, частные для потока . Этот механизм может гарантировать каждому потоку доступ к своей отдельной копии данных, не беспокоясь о синхронизации доступа с другими потоками.


Существует два метода использования TLS:

  1. неявно: используется ключевое слово

    Windows: __declspec (thread) int tls_var = 10;

    Linux с GCC: __thread int tls_var = 10

  2. явно: с использованием определенного API, связанного с TLS

    Windows

    Подробную информацию см. В MSDN.

    LInux с GCC:

    Обратитесь к man-странице для конкретной и подробной информации.
1 голос
/ 18 апреля 2010

Большинство компиляторов имеют некоторый способ обозначения локального хранилища потока.Предполагая, что это доступно, это то, что вы хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...