Чтобы понять, как подойти к созданию «полуширокого» интерфейса, построим интерфейсный класс для POSIX-семафора. И хотя семафор не является частью библиотеки Pthread, он находит аналогичные применения в многопоточной среде. Его можно использовать в среде, которая включает параллельно выполняемые процессы и потоки. Поэтому в некоторых случалх требуется объект синхронизации более общего характера, чем наш класс mutex.
Определение класса semaphore показано в листинге 11.10.
// Листинг 11.10. Объявление класса semaphore
>class semaphore : public synchronization_variable( protected:
>sem_t * Semaphore; public://.. .
>int lock(void);
>int unlock(void);
>int trylock(void);
>//. . .
>};
Синопсис
int sem_init(sem_t *, int, unsigned int) ;
int sem_destroy(sem_t *);
sem_t *sem_open(const char *, int, ...);
int sem_close(sem_t *);
int sem_unlink(const char *);
int sem_wait(sem_t *);
int sem_trywait(sem_t *);
int sem_post(sem_t *);
int sem_getvalue(sem__t *, int *);
Обратите внимание на то, что класс semaphore имеет такой же интерфейс, как и наш класс mutex. Чем же они различаются? Хотя интерфейсы классов mutex и semaphore одинаковы, реализация функций lock (), unlock (), trylock () и тому подобных представляет собой вызовы семафорных функций библиотеки POSIX .
>// Листинг 11.11. Определение методов lock(), unlock() и
>// trylock() для класса semaphore
>int semaphore::lock(void) (
>//.. .
>return(sem_wait(Semaphore));
>}
>int semaphore::unlock(void) {
>//. . .
>return(sem_post(Semaphore));
>}
Итак, теперь функции lock (), unlock (), trylock () и тому подобные заключают в оболочку семафорные функции библиотеки POSIX, а не функции библиотеки Pthread. Важно отметить, что семафор и мьютекс — не одно и то же. Но их можно использовать в аналогичных ситуациях. Зачастую с точки зрения инструкций, которые реализуют параллелизм, механизмы функций lock() и unlock() имеют одно и то же назначение. Некоторые основные различия между мьютексом и семафором указаны в табл. 11.2.
Таблица 11.2. Основные различия между мьютексами и семафорами
• Характеристики мьютексов
• Мьютексы и переменные условий разделяются между потоками
• Мьютекс деблокируется теми же потоками, которые его заблокировали
• Мьютекс либо блокируется, либо деблокируется
• Характеристики семафоров
• Семафоры обычно разделяются между процессами, но их разделение возможно и между потоками
• - Освобождать семафор должен необязательно тот процесс или поток, который его удерживал
• Семафоры управляются количеством ссылок. Стандарт POSIX включает именованные семафоры