PTHREAD_MUTEX_INITIALIZER проти pthread_mutex_init (& mutex, param)


90

Чи є якась різниця між

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

Або

pthread_mutex_t lock;
pthread_mutex_init ( &lock, NULL);

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

ПРИМІТКА. Моє запитання здебільшого стосується дуже маленьких програм, де щонайбільше я буду підключати декілька клієнтів до сервера та вирішувати їх запити за допомогою робочих потоків.

Відповіді:


74

У старих версіях стандарту POSIX перший метод з ініціалізатором гарантовано працює лише зі статично розподіленими змінними, а не тоді, коли змінна є autoзмінною, яка визначена в тілі функції. Хоча я ніколи не бачив платформи, де це не дозволялося б навіть для autoзмінних, і це обмеження було знято в останній версії стандарту POSIX.

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

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


8

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

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


" плюс ви можете використовувати динамічний метод, лише якщо додаєте купу мьютексів під час виконання. " Отже, що це означає? Невеликий приклад, якщо це непросто пояснити?
Kalec

1
@Kalec: якщо ваш мьютекс виділено malloc()(або належить об'єкту, який виділено).
Michael Burr

3
@Kalec, якщо змінна mutex "lock" є частиною структури, то ми не можемо слідувати 1-му підходу. ми повинні використовувати pthread_init ().
pankaj kushwaha

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 просто використовує значення за замовчуванням. У будь-якому випадку це працює , але ми зазвичай використовуємо динамічний (останній) метод.


5

У випадках, коли атрибути mutex за замовчуванням є відповідними, макрос PTHREAD_MUTEX_INITIALIZER може бути використаний для ініціалізації мьютексів.

Якщо ви хочете вказати атрибути для mutex, перейдіть з динамічною ініціалізацією ........

Ефект повинен бути еквівалентний динамічній ініціалізації викликом pthread_mutex_init () з параметром attrs, вказаним як NULL, за винятком того, що перевірка помилок не проводиться.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.