pthread_key_t и pthread_once_t? - PullRequest
       15

pthread_key_t и pthread_once_t?

3 голосов
/ 04 августа 2009

Начиная с pthreads, я не могу понять, что происходит с pthread_key_t и pthread_once_t?

Может ли кто-нибудь объяснить простыми словами примеры, если это возможно?

спасибо

Ответы [ 3 ]

13 голосов
/ 04 августа 2009

pthread_key_t предназначен для создания потока локального хранилища потока : каждый поток получает свою собственную копию переменной данных вместо всех потоков, совместно использующих глобальную (или функционально-статическую, класс-статическую) переменную , TLS индексируется ключом. См. pthread_getspecific и др. Для получения более подробной информации.

pthread_once_t - это элемент управления для выполнения функции только один раз с pthread_once. Предположим, вам нужно вызвать процедуру инициализации, но вы должны вызывать эту процедуру только один раз. Кроме того, точка, в которую вы должны позвонить, это после того, как вы уже запустили несколько потоков. Один из способов сделать это - использовать pthread_once(), который гарантирует, что ваша подпрограмма будет вызываться только один раз, независимо от того, сколько потоков пытается вызвать ее одновременно, при условии, что вы используете одну и ту же переменную управления в каждом вызове. Часто проще использовать pthread_once(), чем использовать другие альтернативы.

11 голосов
/ 04 августа 2009

Нет, это нельзя объяснить с точки зрения непрофессионала. Laymen не может успешно программировать с pthreads в C ++. Требуется специалист, известный как «программист»: -)

pthread_once_t - это небольшой объем памяти, к которому pthread_once должен получить доступ, чтобы убедиться, что он выполняет то, что говорит на жестяной банке. Каждый однократный элемент управления позволяет вызывать процедуру init один раз и только один раз, независимо от того, сколько раз она вызывается из какого количества потоков, возможно одновременно. Обычно вы используете разные однократные элементы управления для каждого объекта, который планируете инициализировать по требованию потокобезопасным способом. Вы можете думать об этом как о целом числе, к которому атомарно обращаются, как о флаге, был ли выбран поток для инициализации. Но поскольку pthread_once блокирует, я полагаю, что здесь есть что-то большее, чем если бы реализация могла втиснуть в примитив синхронизации тоже (единственный раз, когда я реализовал pthread_once, я не смог, так что один раз управление приняло любое из 3 состояний (начало, инициализация, завершение). Но потом я не смог изменить ядро. Необычная ситуация).

pthread_key_t похоже на индекс для доступа к локальному хранилищу потока. Вы можете думать о каждом потоке как о наличии карты от ключей к значениям. Когда вы добавляете новую запись в TLS, pthread_key_create выбирает для нее ключ и записывает этот ключ в указанное вами место. Затем вы используете этот ключ из любого потока, когда хотите установить или получить значение этого элемента TLS для текущего потока. Причина, по которой TLS дает вам ключ вместо того, чтобы позволить вам выбрать один, заключается в том, что несвязанные библиотеки могут использовать TLS, не взаимодействуя друг с другом, чтобы избежать использования одного и того же значения и уничтожения данных TLS друг друга. Библиотека pthread может, например, хранить глобальный счетчик и назначать ключ 0 для первого вызова pthread_key_create, 1 для второго и т. Д.

2 голосов
/ 21 февраля 2013

Ничего себе, другие ответы здесь слишком многословны.

pthread_once_t хранит состояние для pthread_once(). Вызов pthread_once(&s, fn) вызывает fn и устанавливает значение, на которое указывает s, чтобы записать факт его выполнения. Все последующие вызовы pthread_once() являются noops. Имя должно стать очевидным.

pthread_once_t следует инициализировать как PTHREAD_ONCE_INIT.

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