Параллельное и распределенное программирование на С++
Шрифт:
SCHED_FIFO
int pthread_mutexattr_getprioceiling (const pthread_mutexattr_t * restrict attr, int *restrict prioceiling);
int pthread_mutexattr_setprotocol (pthread_mutexattr_t * attr, protocol int protocol);
Устанавливает и возвращает атрибут протокола мьютекса, заданного параметром attr. Параметр protocol может содержать следующие значения:
PTHREAD_PRIO_NONE
(на приоритет и стратегию планирования потока владение мьютексом не оказывает вли
я
ни
я);
int pthread_mutexattr_getprotocol (const pthread_mutexattr_t * restrict attr, int *restrict protocol);
PTHREAD_PRIO_INHERIT
(при
PTHREAD_PRIO_PROTECT
(при таком протоколе потоки, владеющие таким мьютексом, будут выполняться при наивысших предельных значениях приоритетов всех мьютексов, которыми владеют эти потоки, независимо оттого, заблокированы ли другие потоки по каким-то из этих мьютексов)
int pthread_mutexattr_setpshared (pthread_mutexattr_t * attr, int pshared);
Устанавливает и возвращает атрибут process-shared мьютексного атрибутного объекта, заданного параметром attr. Параметр pshared может содержать следующие значения:
int pthread_mutexattr_getpshared (const pthread_mutexattr_t * restrict attr, int *restrict pshared);
PTHREAD_PROCESS_SHARED
(разрешает разделять мьютекс с любыми потоками, которые имеют доступ к выделенной для этого мьютекса памяти, даже если эти потоки принадлежат различным процессам);
PTHREAD_PROCESS_PRIVATE
(мьютекс разделяется между потоками одного и того же процесса)
int pthread_mutexattr_settype (pthread_mutexattr_t* attr, int type);
Устанавливает и возвращает атрибут мьютекса
type
мьютексного атрибутного объекта, заданного параметром
attr
. Атрибут мьютекса
type
позволяет определить, будет ли мьютекс распознавать взаимоблокировку, проверять ошибки и т.д. Параметр
type
может содержать такие значения:
int
PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_ERRORCHECK PTHREAD_MUTEX_NORMAL
pthread_mutexattr_gettype (const pthread_mutexattr_t * restrict attr, int *restrict type);
Самый большой интерес представляет установка атрибута, связанного с тем, каким должен быть мьютекс:
Использование мьютексных семафоров для управления критическими разделами
Мьютексы используются для управления критическими разделами процессов и потоков, чтобы предотвратить возникновение условий «гонок». Мьютексы позволяют избежать условий «гонок», реализуя последовательный доступ к критическому разделу. Рассмотрим код листинга5.1. В нем демонстрируется выполнение двух потоков. Для защиты их критических разделов и используются мьютексы.
// Листинг 5.1. Использование мьютексов для защиты
// критических разделов потоков
// . . .
pthread_t ThreadA, ThreadB; pthread_mutex_t Mutex,-pthread_mutexattr_t MutexAttr;
void *task1(void *X) {
pthread_mutex_lock(&Mutex); // Критический раздел кода.
pthread_mutex_unlock(&Mutex);
return(0) ;
}
void *task2 (void *X) {
pthread_mutex_lock(&Mutex) ;
// Критический раздел кода.
pthread_mutex_unlосk (&Mu t ex) ; return(0) ;
}
int main(void) {
//...
pthread_mutexattr_init (&MutexAttr) ;
pthread_mutex_init (&Mutex, &MutexAttr) ;
//Устанавливаем атрибуты мьютекса.
pthread_create(&ThreadA, NULL, taskl, NULL) ; pthread_create(&ThreadB,NULL, task2,NULL) ;
//...
return(0) ;
}
В листинге 5.1 потоки ThreadA и ThreadB содержат критические разделы, защищаемые с помощью объекта Mutex.
В листинге 5.2 демонстрируется, как можно использовать мьютексы для защиты критических разделов процессов.
// Листинг 5.2. Использование мьютексов для зашиты
// критических разделов процессов
//...
int Rt;
pthread_mutex_t Mutexl ; pthread_mutexattr_t MutexAttr;
int main(void) {
//...
pthread_mutexattr_init (&MutexAttr); pthread_mutexattr_setpshared(
&MutexAttr,
PTHREAD_PROCESS_SHARED ) ;
pthread_mutex_init (&Mutexl, &MutexAttr) ; if((Rt = fork) == 0){
// Сыновний процесс.
pthread_mutex_lock(&Mutexl);