PTHREAD_MUTEX_INITIALIZER против pthread_mutex_init (& мьютекс, параметр)

91

Есть ли разница между

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

Или

pthread_mutex_t lock;
pthread_mutex_init ( &lock, NULL);

Достаточно ли я в безопасности, если использую только первый метод?

ПРИМЕЧАНИЕ. Мой вопрос в основном относится к очень маленьким программам, где самое большее, что я буду делать, - это подключать несколько клиентов к серверу и разрешать их запросы с помощью рабочих потоков.

Калец
источник

Ответы:

74

В более старых версиях стандарта POSIX первый метод с инициализатором гарантированно работает только со статически распределенными переменными, а не тогда, когда переменная является autoпеременной, которая определена в теле функции. Хотя я никогда не видел платформы, где это было бы запрещено даже для autoпеременных, и это ограничение было снято в последней версии стандарта POSIX.

staticВариант действительно предпочтительнее , если вы можете, так как он позволяет писать код начальной загрузки гораздо проще. Всякий раз, когда во время выполнения вы вводите код, который использует такой мьютекс, вы можете быть уверены, что мьютекс инициализирован. Это ценная информация в контексте многопоточности.

Метод, использующий функцию инициализации, предпочтительнее, когда вам нужны специальные свойства для вашего мьютекса, такие как рекурсивность, например, или совместное использование между процессами, а не только между потоками.

Йенс Густедт
источник
8

Вы можете установить больше атрибутов мьютекса с помощью динамической инициализации, плюс вы можете использовать динамический метод, только если вы добавляете кучу мьютексов во время выполнения.

Однако нет ничего плохого в статическом подходе, если он соответствует вашим потребностям.

Джо
источник
« плюс вы можете использовать динамический метод только в том случае, если вы добавляете кучу мьютексов во время выполнения». Итак, что это означает? Небольшой пример, если это непросто объяснить?
Kalec
1
@Kalec: если ваш мьютекс выделен malloc()(или принадлежит объекту, который выделен).
Майкл Берр
3
@Kalec, если мьютексная переменная "lock" является частью структуры, то мы не можем следовать 1-му подходу. мы должны использовать pthread_init ().
панкадж кушваха
8

Я хотел бы процитировать это из этой книги :

С POSIXпотоками есть два способа инициализировать блокировки. Один из способов сделать это - использовать PTHREAD_MUTEX_INITIALIZERследующее: pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

Это устанавливает для блокировки значения по умолчанию и, таким образом, делает блокировку пригодной для использования. Динамический способ сделать это (т. Е. Во время выполнения) - это сделать следующий вызов pthread_mutex_init(): int rc = pthread_mutex_init(&lock, NULL); assert(rc == 0); // always check success!

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

Мари202
источник
5

В случаях, когда подходят атрибуты мьютексов по умолчанию, для инициализации мьютексов можно использовать макрос PTHREAD_MUTEX_INITIALIZER.

Если вы хотите указать атрибуты для мьютекса, используйте динамическую инициализацию ........

Эффект должен быть эквивалентен динамической инициализации путем вызова pthread_mutex_init () с параметром attrs, заданным как NULL, за исключением того, что проверки ошибок не выполняются.

Рамеш Мирияла
источник