Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Несколько запусков по условному сигналу
Для мультипроцессора, скорее всего, невозможно применить функцию pthread_cond_signal(), чтобы избежать разблокировки нескольких потоков, заблокированных с использованием условной переменной. Рассмотрим, например, следующую частичную реализацию функций pthread_cond_wait () и pthread_cond_ signal(), выполняемых потоками в заданном порядке. Один поток пытается «дождаться» нужного значения условной переменной, другой при этом выполняет функцию pthread_cond_signal(), в то время как третий поток уже находится в состоянии ожидания. pthread_cond_wait(mutex, cond): value = cond-> value; /* 1 */ pthread_mutex_unlock (mutex); /* 2 */ pthread_mutex_lock (cond-> mutex); /* 10 */ if (value == cond-> value) { /* 11 */ me-> next_cond = cond-> waiter; cond-> waiter = me; pthread_mutex_unlock(cond-> mutex); unable_to_run (me); } else pthread_mutex_unlock (cond-> mutex); /* 12 */ pthread_mutex_lock (mutex); /* 13 * / pthread_cond_signal (cond): pthread_mutex_lock (cond-> mutex); /* 3 */ cond-> value++; /* 4 */ if (cond-> waiter) { /* 5 */ sleeper = cond-> waiter; /* 6 */ cond-> waiter = sleeper-> next_cond; /* 7 */ able_to_run (sleeper); /* 8 */ } pthread_mutex_unlock (cond-> mutex); /* 9 */ Итак, в результате одного обращения к функции pthread_cond_signal () сразу несколько потоков могут вернуться из вызова функции pthread_cond_wait () или pthread_cond_timedwait (). Такой эффект называется «фиктивным запуском». Обратите внимание на то, что подобная ситуация является самокорректирующейся благодаря тому, что количество потоков, «пробуждающихся» таким путем, ограничено; например, следующий поток, который вызывает функцию pthread_cond_wait (), после определенной последовательности событий блокируется. Несмотря на то что эту проблему можно было бы решить, потеря эффективности ради обработки дополнительного условия, которое возникает лишь иногда, неприемлема, особенно в случае, когда нужно протестировать предикат, связанный с условной переменной. Корректировка этой проблемы слишком уж понизила бы уровень параллелизма в этом базовом стандартном блоке при выполнении всех высокоуровневых операций синхронизации. В разрешении «фиктивных запусков» есть одно дополнительное преимущество: знал о них, разработчикам приложений придется прелусмотреть цикл тестирования предиката при ожидании наступления нужного условия. Это также вынудит приложение «терпеливо» отнестись к распространению «лишних» условных сигналов, связанных с одной и той же условной переменной, формирование которых может быть закодировано в какой-то другой части приложения. В результате приложения станут более устойчивыми. Поэтому в стандарте IEEE Std 1003.1-2001 в прямой форме отмечена возможность возникновения «фиктивных запусков».
|